diff --git a/core/artwork/reader_resized.go b/core/artwork/reader_resized.go index cd16cbada..0cbe6abd0 100644 --- a/core/artwork/reader_resized.go +++ b/core/artwork/reader_resized.go @@ -66,8 +66,12 @@ func resizedFromOriginal(ctx context.Context, a *artwork, artID model.ArtworkID, return r, nil } +// resizedKeyVersion invalidates resized entries cached by pre-blurhash versions: the refill is what +// pulls the original through the tee, so warm entries would otherwise never backfill a hash. +const resizedKeyVersion = "v1" + func (a *resizedArtworkReader) Key() string { - baseKey := fmt.Sprintf("%s.%d", a.cacheKey, a.size) + baseKey := fmt.Sprintf("%s.%d.%s", a.cacheKey, a.size, resizedKeyVersion) if a.square { return baseKey + ".square" } diff --git a/core/artwork/reader_resized_test.go b/core/artwork/reader_resized_test.go index 7c14f5e44..6b419c8bc 100644 --- a/core/artwork/reader_resized_test.go +++ b/core/artwork/reader_resized_test.go @@ -6,12 +6,28 @@ import ( "errors" "io" + "github.com/navidrome/navidrome/conf" + "github.com/navidrome/navidrome/conf/configtest" "github.com/navidrome/navidrome/core/ffmpeg" "github.com/navidrome/navidrome/tests" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) +var _ = Describe("resizedArtworkReader.Key", func() { + BeforeEach(func() { + DeferCleanup(configtest.SetupConfig()) + conf.Server.CoverArtQuality = 75 + }) + + It("includes the cache version so pre-blurhash resized entries are invalidated", func() { + r := &resizedArtworkReader{cacheKey: "al-1.123", size: 300} + Expect(r.Key()).To(Equal("al-1.123.300.v1.75")) + r.square = true + Expect(r.Key()).To(Equal("al-1.123.300.v1.square")) + }) +}) + var _ = Describe("resizeImage", func() { var mockFF *tests.MockFFmpeg var r *resizedArtworkReader