feat: retry async image tasks

This commit is contained in:
QiuSW
2026-07-09 14:46:09 +08:00
parent e3598bfe8b
commit 8878769ec5
16 changed files with 550 additions and 42 deletions
+31 -1
View File
@@ -242,6 +242,9 @@ Content-Type: application/json
"call_id": 12346,
"points_cost": 10,
"points_balance": 88,
"attempt_count": 0,
"max_attempts": 3,
"next_attempt_at": null,
"created_at": "2026-07-08T21:30:00+08:00",
"expires_at": "2026-07-09T21:30:00+08:00"
}
@@ -256,6 +259,7 @@ Content-Type: application/json
- 桌面端主链路推荐传 `image_base64`。该路径在 submit 阶段只做解码和输入文件落盘,不发生外部网络请求,提交请求应保持短耗时。
- `image_url` 仍按同步接口的 SSRF 与大小规则处理,并在 submit 阶段下载成输入文件引用;失败不扣点。这个路径可能因远程图片下载变慢而让 submit 阻塞,适合作为边缘兼容能力,不建议桌面端批量生图主流程使用。
- worker 执行时会复审 prompt 并重解析当前别名 / Provider 配置,但账务使用提交阶段已预扣的 `CallRecord.points_cost`,不会重复扣点。若排队时间较长且后台切换别名,可能出现按提交时价格预扣、按执行时模型运行;未来如需强一致模型选择,应单独实现提交时模型配置快照。
- T-616 起异步 worker 对临时性上游失败自动重试,默认最多 3 次上游调用(第 1 次执行 + 2 次重试)。提交阶段仍只预扣一次;重试等待期间任务状态回到 `queued`,点数暂不退回,最终失败才退款。
### `GET /api/v1/generate/image/tasks/{task_id}`
@@ -274,12 +278,32 @@ Authorization: Bearer sk_cmhub_xxx
"status": "running",
"call_id": 12346,
"points_cost": 10,
"attempt_count": 1,
"max_attempts": 3,
"next_attempt_at": null,
"created_at": "2026-07-08T21:30:00+08:00",
"updated_at": "2026-07-08T21:30:05+08:00",
"expires_at": "2026-07-09T21:30:00+08:00"
}
```
临时性上游失败等待重试时仍返回 `queued`:
```json
{
"task_id": "2bff8217-47a9-44f1-9bd9-82a375e79dc9",
"status": "queued",
"call_id": 12346,
"points_cost": 10,
"attempt_count": 1,
"max_attempts": 3,
"next_attempt_at": "2026-07-08T21:30:20+08:00",
"created_at": "2026-07-08T21:30:00+08:00",
"updated_at": "2026-07-08T21:30:10+08:00",
"expires_at": "2026-07-09T21:30:00+08:00"
}
```
成功:
```json
@@ -288,6 +312,9 @@ Authorization: Bearer sk_cmhub_xxx
"status": "succeeded",
"call_id": 12346,
"points_cost": 10,
"attempt_count": 3,
"max_attempts": 3,
"next_attempt_at": null,
"created_at": "2026-07-08T21:30:00+08:00",
"updated_at": "2026-07-08T21:31:40+08:00",
"expires_at": "2026-07-09T21:30:00+08:00",
@@ -305,6 +332,9 @@ Authorization: Bearer sk_cmhub_xxx
"status": "failed",
"call_id": 12346,
"points_cost": 10,
"attempt_count": 3,
"max_attempts": 3,
"next_attempt_at": null,
"created_at": "2026-07-08T21:30:00+08:00",
"updated_at": "2026-07-08T21:33:00+08:00",
"expires_at": "2026-07-09T21:30:00+08:00",
@@ -315,7 +345,7 @@ Authorization: Bearer sk_cmhub_xxx
}
```
要点:查询只允许任务所属 `user` 与当前 API Key 所属 `user` 一致,跨用户返回 `404 task_not_found`;`succeeded` 重复查询必须返回同一个 `image_url`;`failed` 表示已退款或未扣款,不需要客户端再请求退款。任务元数据默认保留 `IMAGE_TASK_RETENTION_HOURS`(默认 24h),结果图片保留窗口按 `GENERATED_IMAGE_RETENTION_HOURS`(默认 72h)管理;本任务暂不暴露 cancel 路由。
要点:查询只允许任务所属 `user` 与当前 API Key 所属 `user` 一致,跨用户返回 `404 task_not_found`;`succeeded` 重复查询必须返回同一个 `image_url`;`queued` 且 `next_attempt_at` 非空表示正在等待自动重试,客户端继续轮询即可;`failed` 表示最终失败且已退款或未扣款,不需要客户端再请求退款。任务元数据默认保留 `IMAGE_TASK_RETENTION_HOURS`(默认 24h),结果图片保留窗口按 `GENERATED_IMAGE_RETENTION_HOURS`(默认 72h)管理;本任务暂不暴露 cancel 路由。
### `GET /api/v1/balance`