diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index f4e4a164a..ad8287df8 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -29,7 +29,7 @@ func CreateScanner(musicFolder string) scanner.Scanner { dataStore := persistence.New() artworkCache := core.NewImageCache() artwork := core.NewArtwork(dataStore, artworkCache) - cacheWarmer := core.NewCacheWarmer(artworkCache, artwork) + cacheWarmer := core.NewCacheWarmer(artwork) scannerScanner := scanner.New(dataStore, cacheWarmer) return scannerScanner } diff --git a/core/artwork.go b/core/artwork.go index 8c89b3dd2..3a7b771ce 100644 --- a/core/artwork.go +++ b/core/artwork.go @@ -12,6 +12,7 @@ import ( "io" "os" "strings" + "sync" "time" "github.com/deluan/navidrome/core/cache" @@ -205,15 +206,23 @@ func readFromFile(path string) ([]byte, error) { return buf.Bytes(), nil } +var ( + onceImageCache sync.Once + imageCache ArtworkCache +) + func NewImageCache() ArtworkCache { - return cache.NewFileCache("Image", conf.Server.ImageCacheSize, consts.ImageCacheDir, consts.DefaultImageCacheMaxItems, - func(ctx context.Context, arg cache.Item) (io.Reader, error) { - info := arg.(*imageInfo) - reader, err := info.a.getArtwork(ctx, info.id, info.path, info.size) - if err != nil { - log.Error(ctx, "Error loading artwork art", "path", info.path, "size", info.size, err) - return nil, err - } - return reader, nil - }) + onceImageCache.Do(func() { + imageCache = cache.NewFileCache("Image", conf.Server.ImageCacheSize, consts.ImageCacheDir, consts.DefaultImageCacheMaxItems, + func(ctx context.Context, arg cache.Item) (io.Reader, error) { + info := arg.(*imageInfo) + reader, err := info.a.getArtwork(ctx, info.id, info.path, info.size) + if err != nil { + log.Error(ctx, "Error loading artwork art", "path", info.path, "size", info.size, err) + return nil, err + } + return reader, nil + }) + }) + return imageCache } diff --git a/core/cache_warmer.go b/core/cache_warmer.go index 58e5735b9..12bf296dd 100644 --- a/core/cache_warmer.go +++ b/core/cache_warmer.go @@ -14,10 +14,9 @@ type CacheWarmer interface { Flush(ctx context.Context) } -func NewCacheWarmer(cache ArtworkCache, artwork Artwork) CacheWarmer { +func NewCacheWarmer(artwork Artwork) CacheWarmer { w := &warmer{ artwork: artwork, - cache: cache, albums: map[string]struct{}{}, } p, err := pool.NewPool("artwork", 3, &artworkItem{}, w.execute) @@ -33,7 +32,6 @@ func NewCacheWarmer(cache ArtworkCache, artwork Artwork) CacheWarmer { type warmer struct { pool *pool.Pool artwork Artwork - cache ArtworkCache albums map[string]struct{} } diff --git a/core/media_streamer.go b/core/media_streamer.go index e3612400c..499af3816 100644 --- a/core/media_streamer.go +++ b/core/media_streamer.go @@ -6,6 +6,7 @@ import ( "io" "mime" "os" + "sync" "time" "github.com/deluan/navidrome/conf" @@ -167,21 +168,29 @@ func selectTranscodingOptions(ctx context.Context, ds model.DataStore, mf *model return } +var ( + onceTranscodingCache sync.Once + transcodingCache TranscodingCache +) + func NewTranscodingCache() TranscodingCache { - return cache.NewFileCache("Transcoding", conf.Server.TranscodingCacheSize, - consts.TranscodingCacheDir, consts.DefaultTranscodingCacheMaxItems, - func(ctx context.Context, arg cache.Item) (io.Reader, error) { - job := arg.(*streamJob) - t, err := job.ms.ds.Transcoding(ctx).FindByFormat(job.format) - if err != nil { - log.Error(ctx, "Error loading transcoding command", "format", job.format, err) - return nil, os.ErrInvalid - } - out, err := job.ms.ffm.Start(ctx, t.Command, job.mf.Path, job.bitRate) - if err != nil { - log.Error(ctx, "Error starting transcoder", "id", job.mf.ID, err) - return nil, os.ErrInvalid - } - return out, nil - }) + onceTranscodingCache.Do(func() { + transcodingCache = cache.NewFileCache("Transcoding", conf.Server.TranscodingCacheSize, + consts.TranscodingCacheDir, consts.DefaultTranscodingCacheMaxItems, + func(ctx context.Context, arg cache.Item) (io.Reader, error) { + job := arg.(*streamJob) + t, err := job.ms.ds.Transcoding(ctx).FindByFormat(job.format) + if err != nil { + log.Error(ctx, "Error loading transcoding command", "format", job.format, err) + return nil, os.ErrInvalid + } + out, err := job.ms.ffm.Start(ctx, t.Command, job.mf.Path, job.bitRate) + if err != nil { + log.Error(ctx, "Error starting transcoder", "id", job.mf.ID, err) + return nil, os.ErrInvalid + } + return out, nil + }) + }) + return transcodingCache }