diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 90984c84e..8fb28df38 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -26,7 +26,7 @@ func CreateServer(musicFolder string) *server.Server { func CreateScanner(musicFolder string) scanner.Scanner { dataStore := persistence.New() - artworkCache := core.NewImageCache() + artworkCache := core.GetImageCache() artwork := core.NewArtwork(dataStore, artworkCache) cacheWarmer := core.NewCacheWarmer(artwork) scannerScanner := scanner.New(dataStore, cacheWarmer) @@ -41,10 +41,10 @@ func CreateAppRouter() *app.Router { func CreateSubsonicAPIRouter() *subsonic.Router { dataStore := persistence.New() - artworkCache := core.NewImageCache() + artworkCache := core.GetImageCache() artwork := core.NewArtwork(dataStore, artworkCache) transcoderTranscoder := transcoder.New() - transcodingCache := core.NewTranscodingCache() + transcodingCache := core.GetTranscodingCache() mediaStreamer := core.NewMediaStreamer(dataStore, transcoderTranscoder, transcodingCache) archiver := core.NewArchiver(dataStore) players := core.NewPlayers(dataStore) diff --git a/core/artwork.go b/core/artwork.go index 8c89b3dd2..0c5f0e791 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 } -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 - }) +var ( + onceImageCache sync.Once + instanceImageCache ArtworkCache +) + +func GetImageCache() ArtworkCache { + onceImageCache.Do(func() { + instanceImageCache = 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 instanceImageCache } diff --git a/core/artwork_test.go b/core/artwork_test.go index 91b8e97aa..4401a5015 100644 --- a/core/artwork_test.go +++ b/core/artwork_test.go @@ -5,7 +5,6 @@ import ( "context" "image" "io/ioutil" - "os" "github.com/deluan/navidrome/conf" "github.com/deluan/navidrome/log" @@ -37,15 +36,11 @@ var _ = Describe("Artwork", func() { BeforeEach(func() { conf.Server.DataFolder, _ = ioutil.TempDir("", "file_caches") conf.Server.ImageCacheSize = "100MB" - cache := NewImageCache() + cache := GetImageCache() Eventually(func() bool { return cache.Ready() }).Should(BeTrue()) artwork = NewArtwork(ds, cache) }) - AfterEach(func() { - os.RemoveAll(conf.Server.DataFolder) - }) - It("retrieves the external artwork art for an album", func() { buf := new(bytes.Buffer) diff --git a/core/media_streamer.go b/core/media_streamer.go index e3612400c..6c99aa6d9 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 } -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 - }) +var ( + onceTranscodingCache sync.Once + instanceTranscodingCache TranscodingCache +) + +func GetTranscodingCache() TranscodingCache { + onceTranscodingCache.Do(func() { + instanceTranscodingCache = 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 instanceTranscodingCache } diff --git a/core/media_streamer_test.go b/core/media_streamer_test.go index e2bbb9761..12b3fe745 100644 --- a/core/media_streamer_test.go +++ b/core/media_streamer_test.go @@ -4,7 +4,6 @@ import ( "context" "io" "io/ioutil" - "os" "strings" "github.com/deluan/navidrome/conf" @@ -29,15 +28,11 @@ var _ = Describe("MediaStreamer", func() { ds.MediaFile(ctx).(*tests.MockMediaFile).SetData(model.MediaFiles{ {ID: "123", Path: "tests/fixtures/test.mp3", Suffix: "mp3", BitRate: 128, Duration: 257.0}, }) - testCache := NewTranscodingCache() + testCache := GetTranscodingCache() Eventually(func() bool { return testCache.Ready() }).Should(BeTrue()) streamer = NewMediaStreamer(ds, ffmpeg, testCache) }) - AfterEach(func() { - os.RemoveAll(conf.Server.DataFolder) - }) - Context("NewStream", func() { It("returns a seekable stream if format is 'raw'", func() { s, err := streamer.NewStream(ctx, "123", "raw", 0) diff --git a/core/wire_providers.go b/core/wire_providers.go index dec7edfe1..32c955b5e 100644 --- a/core/wire_providers.go +++ b/core/wire_providers.go @@ -13,8 +13,8 @@ import ( var Set = wire.NewSet( NewArtwork, NewMediaStreamer, - NewTranscodingCache, - NewImageCache, + GetTranscodingCache, + GetImageCache, NewArchiver, NewNowPlayingRepository, NewExternalInfo,