Disk cache: version the poster folder

Posters stored by the previous build (the downloaded bytes, for real
images Radarr's 333x500 copy) were reused as they were for 30 days.
Posters now live in posters-v2/; older folders are deleted at startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 11:41:11 +02:00
co-authored by Claude Opus 5.5
parent 15e97f4582
commit ca8c71fa52
4 changed files with 33 additions and 4 deletions
+14 -2
View File
@@ -18,8 +18,17 @@ const (
posterCacheCap = 200 << 20 // bytes of posters kept on disk
peopleTTL = 7 * 24 * time.Hour // a cast on disk is used this long
maxPeopleSaved = 2000 // casts kept (in memory and on disk)
// postersDir names the poster folder for the current way of storing them
// (v2: as decoded, at the size used). Folders of older ways are deleted by
// prunePosters: their files would otherwise be used as they are (v1 kept
// Radarr's 333×500 copies for real images).
postersDir = "posters-v2"
)
// oldPosterDirs are poster folders of earlier versions.
var oldPosterDirs = []string{"posters"}
// cacheDirFunc returns the directory for the disk cache, "" for none. It is a
// variable so tests can turn the cache off.
var cacheDirFunc = func() string {
@@ -42,7 +51,7 @@ func (d *diskCache) posterPath(key string, large bool) string {
size = "large"
}
sum := sha256.Sum256([]byte(size + "|" + key))
return filepath.Join(d.dir, "posters", hex.EncodeToString(sum[:16])+".img")
return filepath.Join(d.dir, postersDir, hex.EncodeToString(sum[:16])+".img")
}
// readPoster returns the stored bytes of a poster, if they are not too old.
@@ -85,9 +94,12 @@ func (d *diskCache) prunePosters() {
size int64
mod time.Time
}
for _, old := range oldPosterDirs {
_ = os.RemoveAll(filepath.Join(d.dir, old))
}
var files []file
var total int64
_ = filepath.WalkDir(filepath.Join(d.dir, "posters"), func(p string, e fs.DirEntry, err error) error {
_ = filepath.WalkDir(filepath.Join(d.dir, postersDir), func(p string, e fs.DirEntry, err error) error {
if err != nil || e.IsDir() {
return nil
}
+16
View File
@@ -105,3 +105,19 @@ func TestPeopleCacheKeepsTheNewest(t *testing.T) {
t.Error("new casts must be written")
}
}
func TestPostersOfOlderVersionsAreDropped(t *testing.T) {
d := &diskCache{dir: t.TempDir()}
old := filepath.Join(d.dir, "posters", "abc.img")
if err := writeAtomic(old, []byte("v1")); err != nil {
t.Fatal(err)
}
d.writePoster("k", true, []byte("v2"))
d.prunePosters()
if _, err := os.Stat(old); !os.IsNotExist(err) {
t.Error("a poster of the old format was kept")
}
if data, ok := d.readPoster("k", true); !ok || string(data) != "v2" {
t.Error("the current poster was dropped")
}
}