docs: record the detail replacement durable batch incident and rollout
This commit is contained in:
parent
0907aaff67
commit
db3a038b00
@ -0,0 +1,41 @@
|
||||
# 风格化“详情替换”长时间不出结果(2026-09-26)
|
||||
|
||||
## 现场证据
|
||||
|
||||
用户截图中的风格化项目已保存 33 张目标详情参考图,但输入图区为 0 张、结果图为 0 张。卡片上的 96% 不是服务商进度:`DetailResultProcessingScanOverlay` 按 240 秒把时间线性映射成百分比,并用 `Math.min(96, ...)` 封顶,所以只要没收到结果,它就会一直停在 96%。
|
||||
|
||||
生成请求走的是浏览器保持的对话流(`/api/chat` 的 SSE)。切换标签页、断网或连接中断后服务端结果无法回传,前端那条“处理中”的状态又存在浏览器里,重新打开页面会继续播放假进度,因此表现为“挂几个小时”。
|
||||
|
||||
另外确认了一个独立故障:详情替换专用模型绑定为 `gpt-image-2.5-flare`,该型号当时持续返回 HTTP 404;普通 `gpt-image-2.5` 有成功出图记录。2026-09-24 17:45 已把线上 `SystemSettings.detail_replacement_image_model_config.modelId` 热更新为 `gpt-image-2.5`。
|
||||
|
||||
上线前线上 `CanvasImageTask` 中 `taskKind = 'agent-detail-replacement-batch'` 的行数为 0,即任务从未进过服务端队列,符合“没有可恢复任务、只能挂假进度”的判断。
|
||||
|
||||
## 修复
|
||||
|
||||
- 详情替换改为服务器端后台批次:`POST /api/agents/detail-replacement/batches` 先落 `CanvasImageTask`,由 `lib/agents/detail-replacement-batch-runner.ts` 按参考图逐张生成,每张结果即时写回项目(`persistAgentDetailReplacementCard`)并更新任务进度。
|
||||
- 页面不再依赖长连接:卡片状态来自任务查询(3 秒轮询 + 回到前台重新校验),刷新、切换标签页、换浏览器都能按任务状态恢复;没有后端批次时不再显示“处理中”。
|
||||
- 删除按时间爬到 96% 的假进度动画,进度改为真实的排队 / 生成中 / 已完成 / 失败。
|
||||
- 提交前校验:没有产品输入图直接拦截提示补图;参考图必须与项目已保存的一致;配额与积分不足在提交阶段返回明确错误。
|
||||
- 服务重启恢复:`instrumentation.ts` 启动 5 秒后以及之后每 60 秒调用 `resumeDetailReplacementBatchTasks()`,把 `pending` 或心跳停滞(>90 秒无 `updatedAt`)的批次重新入队;运行期间每 30 秒写心跳。
|
||||
- 长批次不再被清理规则误判:详情替换的运行超时单独放宽到 3 小时,`markStaleDatabaseRunningTasksFailed` 与 `getCanvasImageTaskForUser` 都排除该任务类型。
|
||||
- 单张失败只落到该卡片并继续后续图片;已写入项目的卡片在恢复时按批次号 + 卡片号认领,不重复调用模型、不重复记账。
|
||||
- 去重按“同一份提交内容”而不是“同一项目”:`submissionKey` 覆盖参考图集合、提示词、模型、尺寸等,配合局部唯一索引 `CanvasImageTask_detail_batch_submission_key` 拦住重复点击;单张重新生图因为卡片集合不同,不会被吞掉。
|
||||
- 详情替换默认模型由 `gpt-image-2.5-flare` 改回 `gpt-image-2.5`(`lib/ai/detail-replacement-image-model-config.ts` + 迁移 `0101`),并保留前端传参路径不变。
|
||||
|
||||
## 验证
|
||||
|
||||
- 服务端链路端到端验证(生产库,纯沿用卡片,不调用模型、不消耗积分):直接插入 `pending` 批次后,恢复循环在 60 秒内接手,任务转为 `succeeded`,两张卡片写入项目 `replacementResultState.detail_replacement`,聊天记录写入 2 条对应结果消息;验证数据随后全部删除,线上无残留。
|
||||
- 重启幂等验证:把同一任务改回 `pending`,恢复后 `attempts` 1 → 2,已完成卡片被跳过,结果卡片与消息条数不变,确认不会重复生成、重复记账。
|
||||
- 本地 `tsc --noEmit`、Next.js 生产构建、`git diff --check` 通过;`tests/routes/detail-replacement-batch.test.ts` 与 `tests/routes/replacement-product-identity.test.ts` 共 12 项通过,覆盖批次识别、卡片消息 ID 稳定性、重启跳过已完成卡片、提交键去重与单张重跑区分。
|
||||
|
||||
## 发布
|
||||
|
||||
2026-09-26 02:45 发布至 45.192.99.48 / ai.yydd.ai。生产代码提交 `0907aaff`,构建目录 `.next-detail-batch-0907aaff-20260926T023939`(BUILD_ID `0wcSfql6ZB2g8EzNEP6Gy`)。切换 `.next` 符号链接后 `pm2 restart ai-chatbot`。
|
||||
|
||||
回滚点记录在服务器 `/root/detail-batch-rollback.txt`:旧提交 `1c2acee5`、旧构建 `.next-video-home-439af60c-20260924`。回滚只需把 `.next` 指回旧目录并重启。
|
||||
|
||||
服务器构建使用 `NEXT_IGNORE_BUILD_TYPECHECK=1`:该机器上遗留的 `backups/next-before-vip98k-0911/types/validator.ts` 会被 `tsconfig` 的 `**/*.ts` 扫到,它的相对导入在该目录下必然失效;同一提交已在本地跑通完整类型检查与构建。
|
||||
|
||||
线上检查:登录页 200、首页 200、未登录访问 `/api/agents/detail-replacement/batches` 返回 401;数据库去重索引已建,`CanvasImageTask` 无遗留批次。分支 `codex/detail-recovery-0924` 已推送 Git。
|
||||
|
||||
发布时经确认近 3 小时无任何生成任务、近 1 小时无新消息,重启未打断在途生成。
|
||||
Loading…
x
Reference in New Issue
Block a user