相册缩略图"小红叉"问题修复记录(2026-09-10)
现象
- ComfyUI 出图后,相册能很快拉到图并在界面占位,但缩略图位置显示加载失败的小红叉。
定位
- 复现:对最新条目首次请求
/thumb/<id>.jpg → HTTP 500(body 为 "thumb"),第二次请求才 200 出图。
- 即:缩略图首次生成失败时服务端直接返回 500,浏览器立刻显示小红叉;而生成是"按需触发",用户看到的正是首次触发的失败。
- 手动跑 ffmpeg 3 次全部成功(exit 0)、磁盘充足 → 不是 ffmpeg 或磁盘问题,是服务端偶发生成失败/请求被长队列阻塞:
- 偶发 ffmpeg 退出非零(原因待后续日志确认);
- 重启后后台预热队列(368 条)会排在新图请求前面,用户实时请求可能等数十秒。
- 原
doThumb 不记录 ffmpeg stderr,失败原因不可见。
修复(comfyui-gallery/server.js,已重启生效)
- 服务端生成失败自动重试:doThumb 失败后最多重试 2 次(间隔 800ms),并记录 ffmpeg stderr 到 web 日志(后续再失败可直接看到原因)。
- 用户实时请求插队:
ensureThumb(..., prio=true) 时 unshift 到队列头部,优先于后台预热任务,重启后新图不再被几百条预热任务堵住。
- 浏览器端失败自愈:
img.onerror 自动重试最多 3 次(600ms/1.2s/1.8s 退避,带 ?r=N 防缓存),即使服务端偶发 500 也不再永久小红叉。
验证
- 顺序 10 轮"删缩略图→请求":10/10 HTTP 200,无失败、无重试日志。
- 并发 8 个条目同时请求:8/8 HTTP 200,缩略图全部生成,0 缺失。
- 页面客户端脚本语法校验通过。
终版方案(2026-09-10 追加):缩略图就绪后才占位(根治)
问题复盘
此前"首请求才生成缩略图"存在竞态:条目先出现在网格里,浏览器随即请求缩略图,若此刻生成尚未完成/偶发失败 → 500 → 小红叉。重试机制只能减轻,不能根除"看到红叉"。
终版方案(按用户提议:先生成缩略图,确认就绪后再在界面占位)
- 服务端标记就绪状态:
/api/catalog 每条数据新增 th 字段(data/thumbs/<id>.jpg 是否存在)。
- 未就绪条目不请求图片:
th=false 的卡片渲染为"⏳ 缩略图生成中"占位(不含 <img>,不发起请求 → 不可能出现小红叉)。
- 就绪后自动换图:前端列表签名加入
pending: 未就绪数量;后台预热把缩略图生成好后,th 翻转 → 签名变化 → 网格自动重绘为真缩略图。
- 后台增量预热 5s 一轮:新同步条目的缩略图在 meta 写入后 ≤5s 内开始生成(并发 3,单张 ~0.3s),通常 1~8s 内就绪;失败条目 5 分钟冷却防刷。
- 兜底仍在:按需生成(用户请求时)带 2 次内部重试 + stderr 日志;浏览器端 onerror 每 2s 重试 ×8。
验证
- 删掉最新条目缩略图 → catalog 立即
th=false → 8 秒后 th=true,缩略图请求 200 出图(640x1134 JPEG)。
- 页面含占位/签名逻辑,客户端脚本语法校验通过。