From 1465479f2aeccefde2ec97ce11a92fd8e9079d78 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Tue, 18 Jul 2023 18:31:20 -0700 Subject: [PATCH] add expiry to cached full size cover art --- backend/imagecache.go | 9 +++++++++ backend/imagemanager.go | 21 ++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/backend/imagecache.go b/backend/imagecache.go index 299ede6..10257fd 100644 --- a/backend/imagecache.go +++ b/backend/imagecache.go @@ -29,6 +29,12 @@ type ImageCache struct { MaxSize int DefaultTTL time.Duration + // Sets a callback that is invoked whenever the periodic + // eviction has been run. Allows for "tacking on" extra + // cleanup tasks outside of the ImageCache's jurisdiction + // that are run on the same schedule. + OnEvictTaskRan func() + mu sync.RWMutex cache map[string]CacheItem } @@ -157,6 +163,9 @@ func (i *ImageCache) periodicallyEvict(ctx context.Context, interval time.Durati return case <-t.C: i.EvictExpired() + if i.OnEvictTaskRan != nil { + i.OnEvictTaskRan() + } } } } diff --git a/backend/imagemanager.go b/backend/imagemanager.go index b5d4721..d65c07e 100644 --- a/backend/imagemanager.go +++ b/backend/imagemanager.go @@ -20,15 +20,19 @@ import ( const CachedImageValidTime = 24 * time.Hour -const coverArtThumbnailSize = 300 +const ( + coverArtThumbnailSize = 300 + fullSizeCoverExpires = 5 * time.Minute +) type ImageManager struct { s *ServerManager baseCacheDir string thumbnailCache ImageCache - cachedFullSizeCover image.Image - cachedFullSizeCoverID string + cachedFullSizeCover image.Image + cachedFullSizeCoverID string + cachedFullSizeCoverAccessedAt int64 // unixMillis } func NewImageManager(ctx context.Context, s *ServerManager, baseCacheDir string) *ImageManager { @@ -45,6 +49,7 @@ func NewImageManager(ctx context.Context, s *ServerManager, baseCacheDir string) DefaultTTL: 1 * time.Minute, }, } + i.thumbnailCache.OnEvictTaskRan = i.clearExpiredFullSizeCover i.thumbnailCache.Init(ctx, 2*time.Minute) return i } @@ -74,6 +79,7 @@ func (i *ImageManager) GetCoverThumbnailWithTTL(coverID string, ttl time.Duratio func (i *ImageManager) GetFullSizeCoverArt(coverID string) (image.Image, error) { if i.cachedFullSizeCoverID == coverID { + i.cachedFullSizeCoverAccessedAt = time.Now().UnixMilli() return i.cachedFullSizeCover, nil } if i.s.Server == nil { @@ -85,6 +91,7 @@ func (i *ImageManager) GetFullSizeCoverArt(coverID string) (image.Image, error) } i.cachedFullSizeCover = im i.cachedFullSizeCoverID = coverID + i.cachedFullSizeCoverAccessedAt = time.Now().UnixMilli() return im, nil } @@ -215,3 +222,11 @@ func (i *ImageManager) loadLocalImage(path string) (image.Image, bool) { } return nil, false } + +func (i *ImageManager) clearExpiredFullSizeCover() { + now := time.Now().UnixMilli() + if now-i.cachedFullSizeCoverAccessedAt > fullSizeCoverExpires.Milliseconds() { + i.cachedFullSizeCoverID = "" + i.cachedFullSizeCover = nil + } +}