fix(api): lazy cover self-heal + tmp-file skip

This commit is contained in:
2026-09-07 12:44:47 +08:00
parent 4b40dd669b
commit 12f6e82308
2 changed files with 60 additions and 2 deletions
+36 -2
View File
@@ -36,8 +36,42 @@ func (a *api) serveCover(c *gin.Context) {
}
a.immutable(c)
dir := bookfile.CoverDir(a.cfg.CacheDir, bookfile.DirKey(b.ID, bookfile.Hash(b.FileSize, b.ModTS)))
if entries, e := os.ReadDir(dir); e == nil && len(entries) > 0 {
http.ServeFile(c.Writer, c.Request, filepath.Join(dir, entries[0].Name()))
if entries, e := os.ReadDir(dir); e == nil {
for _, en := range entries { // 跳过写一半的 .tmp 落盘中间态
if !strings.Contains(en.Name(), ".tmp") {
http.ServeFile(c.Writer, c.Request, filepath.Join(dir, en.Name()))
return
}
}
}
if b.Format == "cbz" || b.Format == "epub" { // 自愈:缓存丢了就地抽封面(重启/卷漂移/扫描器还没跑到)
if root, ok := a.bookRoot(c, b); ok {
if f, size, ok := a.openBook(c, b, root); ok {
defer f.Close()
var img []byte
var ext string
var e error
if b.Format == "cbz" {
img, ext, e = bookfile.CBZCover(f, size)
} else {
img, ext, e = bookfile.EPUBCover(f, size)
}
if e == nil {
dst := filepath.Join(dir, "cover"+ext)
if e := os.MkdirAll(dir, 0o755); e == nil {
tmp := fmt.Sprintf("%s.tmp-%d", dst, time.Now().UnixNano()) // 并发幂等:唯一 tmp + rename 原子
if e := os.WriteFile(tmp, img, 0o644); e == nil {
if e := os.Rename(tmp, dst); e == nil {
http.ServeFile(c.Writer, c.Request, dst)
}
}
os.Remove(tmp)
}
}
}
}
}
if c.Writer.Written() { // openBook/bookRoot 已写 403/404/500,不再叠加占位图
return
}
c.Data(http.StatusOK, "image/svg+xml", []byte(defaultCover))