Fix memory leak in CachedGenreRepository (#3031)

that the scanner was run, the ttlcache was also created each time.
This caused (under testing with 166 genres in the database) the
memory consumed by navidrome to 101.18MB over approx 3 days; 96%
of which is in instances of this cache. Swapping to a singleton
has reduced this to down to ~ 2.6MB

Co-authored-by: Rob Emery <git@mintsoft.net>
This commit is contained in:
Rob Emery 2024-05-16 16:16:56 +00:00 committed by Joe Stump
parent 9bae65167c
commit ef14eb74f9
No known key found for this signature in database
GPG Key ID: 29151C3EC48A0EB9

View File

@ -8,25 +8,27 @@ import (
"github.com/jellydator/ttlcache/v2"
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/utils/singleton"
)
func newCachedGenreRepository(ctx context.Context, repo model.GenreRepository) model.GenreRepository {
r := &cachedGenreRepo{
GenreRepository: repo,
ctx: ctx,
}
genres, err := repo.GetAll()
if err != nil {
log.Error(ctx, "Could not load genres from DB", err)
return repo
}
return singleton.GetInstance(func() *cachedGenreRepo {
r := &cachedGenreRepo{
GenreRepository: repo,
ctx: ctx,
}
genres, err := repo.GetAll()
r.cache = ttlcache.NewCache()
for _, g := range genres {
_ = r.cache.Set(strings.ToLower(g.Name), g.ID)
}
return r
if err != nil {
log.Error(ctx, "Could not load genres from DB", err)
panic(err)
}
r.cache = ttlcache.NewCache()
for _, g := range genres {
_ = r.cache.Set(strings.ToLower(g.Name), g.ID)
}
return r
})
}
type cachedGenreRepo struct {