From 52235c291d1d3497b3f5c4dbdcf23c0757ef8d60 Mon Sep 17 00:00:00 2001 From: Rob Emery Date: Thu, 16 May 2024 16:16:56 +0000 Subject: [PATCH] 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 --- scanner/cached_genre_repository.go | 32 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/scanner/cached_genre_repository.go b/scanner/cached_genre_repository.go index 99d516a2c..4ff9e6ee0 100644 --- a/scanner/cached_genre_repository.go +++ b/scanner/cached_genre_repository.go @@ -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 {