feat(artwork): add UIThumbnailSize constant and update cache warmer to pre-cache thumbnails

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan
2026-03-18 07:59:10 -04:00
parent 31d94acfe7
commit 00b8fbd789
3 changed files with 40 additions and 9 deletions
+1
View File
@@ -71,6 +71,7 @@ const (
PlaceholderAlbumArt = "album-placeholder.webp"
PlaceholderAvatar = "logo-192x192.png"
UICoverArtSize = 300
UIThumbnailSize = 80
DefaultUIVolume = 100
DefaultUISearchDebounceMs = 200
+9 -8
View File
@@ -142,14 +142,15 @@ func (a *cacheWarmer) doCacheImage(ctx context.Context, id model.ArtworkID) erro
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
r, _, err := a.artwork.Get(ctx, id, consts.UICoverArtSize, true)
if err != nil {
return fmt.Errorf("caching id='%s': %w", id, err)
}
defer r.Close()
_, err = io.Copy(io.Discard, r)
if err != nil {
return err
for _, size := range []int{consts.UICoverArtSize, consts.UIThumbnailSize} {
r, _, err := a.artwork.Get(ctx, id, size, true)
if err != nil {
return fmt.Errorf("caching id='%s', size=%d: %w", id, size, err)
}
defer r.Close()
if _, err = io.Copy(io.Discard, r); err != nil {
return err
}
}
return nil
}
+30 -1
View File
@@ -6,11 +6,13 @@ import (
"fmt"
"io"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/navidrome/navidrome/conf"
"github.com/navidrome/navidrome/conf/configtest"
"github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/utils/cache"
. "github.com/onsi/ginkgo/v2"
@@ -173,20 +175,47 @@ var _ = Describe("CacheWarmer", func() {
return len(cw.buffer)
}).Should(Equal(0))
})
It("pre-caches both UICoverArtSize and UIThumbnailSize", func() {
cw := NewCacheWarmer(aw, fc).(*cacheWarmer)
cw.PreCache(model.MustParseArtworkID("al-1"))
Eventually(func() int {
cw.mutex.Lock()
defer cw.mutex.Unlock()
return len(cw.buffer)
}).Should(Equal(0))
sizes := aw.getCachedSizes()
Expect(sizes).To(ContainElements(consts.UICoverArtSize, consts.UIThumbnailSize))
})
})
})
type mockArtwork struct {
err error
err error
mu sync.Mutex
cachedSizes []int
}
func (m *mockArtwork) Get(ctx context.Context, artID model.ArtworkID, size int, square bool) (io.ReadCloser, time.Time, error) {
if m.err != nil {
return nil, time.Time{}, m.err
}
m.mu.Lock()
m.cachedSizes = append(m.cachedSizes, size)
m.mu.Unlock()
return io.NopCloser(strings.NewReader("test")), time.Now(), nil
}
func (m *mockArtwork) getCachedSizes() []int {
m.mu.Lock()
defer m.mu.Unlock()
result := make([]int, len(m.cachedSizes))
copy(result, m.cachedSizes)
return result
}
func (m *mockArtwork) GetOrPlaceholder(ctx context.Context, id string, size int, square bool) (io.ReadCloser, time.Time, error) {
return m.Get(ctx, model.ArtworkID{}, size, square)
}