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:
@@ -71,6 +71,7 @@ const (
|
|||||||
PlaceholderAlbumArt = "album-placeholder.webp"
|
PlaceholderAlbumArt = "album-placeholder.webp"
|
||||||
PlaceholderAvatar = "logo-192x192.png"
|
PlaceholderAvatar = "logo-192x192.png"
|
||||||
UICoverArtSize = 300
|
UICoverArtSize = 300
|
||||||
|
UIThumbnailSize = 80
|
||||||
DefaultUIVolume = 100
|
DefaultUIVolume = 100
|
||||||
DefaultUISearchDebounceMs = 200
|
DefaultUISearchDebounceMs = 200
|
||||||
|
|
||||||
|
|||||||
@@ -142,14 +142,15 @@ func (a *cacheWarmer) doCacheImage(ctx context.Context, id model.ArtworkID) erro
|
|||||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
r, _, err := a.artwork.Get(ctx, id, consts.UICoverArtSize, true)
|
for _, size := range []int{consts.UICoverArtSize, consts.UIThumbnailSize} {
|
||||||
if err != nil {
|
r, _, err := a.artwork.Get(ctx, id, size, true)
|
||||||
return fmt.Errorf("caching id='%s': %w", id, err)
|
if err != nil {
|
||||||
}
|
return fmt.Errorf("caching id='%s', size=%d: %w", id, size, err)
|
||||||
defer r.Close()
|
}
|
||||||
_, err = io.Copy(io.Discard, r)
|
defer r.Close()
|
||||||
if err != nil {
|
if _, err = io.Copy(io.Discard, r); err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/navidrome/navidrome/conf"
|
"github.com/navidrome/navidrome/conf"
|
||||||
"github.com/navidrome/navidrome/conf/configtest"
|
"github.com/navidrome/navidrome/conf/configtest"
|
||||||
|
"github.com/navidrome/navidrome/consts"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
"github.com/navidrome/navidrome/utils/cache"
|
"github.com/navidrome/navidrome/utils/cache"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
@@ -173,20 +175,47 @@ var _ = Describe("CacheWarmer", func() {
|
|||||||
return len(cw.buffer)
|
return len(cw.buffer)
|
||||||
}).Should(Equal(0))
|
}).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 {
|
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) {
|
func (m *mockArtwork) Get(ctx context.Context, artID model.ArtworkID, size int, square bool) (io.ReadCloser, time.Time, error) {
|
||||||
if m.err != nil {
|
if m.err != nil {
|
||||||
return nil, time.Time{}, m.err
|
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
|
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) {
|
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)
|
return m.Get(ctx, model.ArtworkID{}, size, square)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user