把 checkpoint 分支写实为 at-most-once 硬约束而非续跑能力

- worker.rs 模块注释明确 Tripo job 固定 max_attempts = 1,崩溃后租约耗尽直接终态失败、不会被重新 claim,因此不存在续跑路径
- worker.rs 说明 existing_checkpoint 是防御性硬约束,checkpoint 的日常用途是人工对账
- 技术方案与 ADR 把「崩溃后重新 claim 只查询」改写为「不重新 claim,带 checkpoint 的路径绝不二次 submit」
- 实施计划与里程碑同步 checkpoint 语义,不再宣称续跑
This commit is contained in:
2026-09-23 17:50:04 +08:00
parent 85219ad1d4
commit 985955205c
5 changed files with 18 additions and 10 deletions
@@ -59,11 +59,11 @@ Milestone Spec: `docs/project-memory/plans/【里程碑】Tripo生成Worker执
- 执行分支:无 checkpoint 才 submit,submit 成功后先落 checkpoint 再轮询;已有 checkpoint 只查询、下载与落库;checkpoint 写入失败按失败收口。
- 轮询在单次 attempt 内进行并按现有心跳续租,超时按现有 worker 预算语义处理。
- provider 成功但落库失败按失败收口并冲正扣费,checkpoint 保留供对账。
- 验收:崩溃重放不产生第二次 submit;落库失败不退化成“已交付”。
- 验收:任何带 checkpoint 的执行路径都不产生第二次 submit;`max_attempts = 1` 使崩溃后不重新 claim(不存在续跑);落库失败不退化成“已交付”。
7. **接线与文档**
- `app.rs` merge 新路由;`external_generation_worker.rs` 增加两个分支并纳入长任务超时;`tripo3d/mod.rs` 去掉里程碑一的 `dead_code` 豁免。
- 主规范把 `max_attempts = 1` 与 checkpoint 的实际语义写实,里程碑状态同步。
- 主规范把 `max_attempts = 1` 与 checkpoint 的实际语义写实(at-most-once 硬约束 + 人工对账,不是续跑能力),里程碑状态同步。
- 验收:`node scripts/check-doc-index.mjs`、`npm run check:encoding`、`git diff --check` 通过。
## 进展
@@ -14,7 +14,7 @@ Implementation Plan: `docs/project-memory/plans/【实施计划】Tripo生成Wor
- 两个 Bearer 路由:`/api/assets/tripo/text-to-model`、`/api/assets/tripo/image-to-model`,含 `Idempotency-Key` 校验与错误映射。
- 两个 Tripo job kind 的 worker 分支:submit、单次 `get_task` 轮询、下载、OSS 写入、资源登记、严格结果序列化。
- checkpoint 规则:无 checkpoint 才 submit,submit 成功后先落 checkpoint 再轮询,已有 checkpoint 只续跑;submit 成功但 checkpoint 落库失败的 attempt 终态失败。
- checkpoint 规则:无 checkpoint 才 submit,submit 成功后先落 checkpoint 再轮询,已有 checkpoint 只查询(防御性硬约束,当前 `max_attempts = 1` 下不存在续跑路径);submit 成功但 checkpoint 落库失败的 attempt 终态失败。
- 图片输入的归属校验与 OSS 对象解析;结果落点的两个分支。
- 提交时定价扣费、attempt 级退款、幂等重放不重复扣费。
- 真实 Provider smoke 与端到端验收证据。