feat: add generation job cancel and retry queue

This commit is contained in:
2026-04-19 18:45:34 +08:00
parent 6fb128955f
commit b89ca96e4b
18 changed files with 756 additions and 51 deletions

View File

@@ -126,7 +126,7 @@ DreamWeaver 是面向 3-8 岁亲子场景的个性化 AI 绘本与陪伴式讲
### 2:20 - 3:00 取舍与下一步
求职版优先稳定闭环和可解释性,不做支付、多租户和复杂监控。现在 job/event 已能查询 workflow、资产补全、provider 调用轨迹和聚合指标,用户端和管理端也能展示生成轨迹与跨故事 Provider 运营摘要;下一步会迁移到后台 worker。
求职版优先稳定闭环和可解释性,不做支付、多租户和复杂监控。现在 job/event 已能查询 workflow、资产补全、provider 调用轨迹和聚合指标,用户端和管理端也能展示生成轨迹与跨故事 Provider 运营摘要;统一生成也已经迁移到后台 worker,下一步是补取消/重试队列
---

View File

@@ -51,7 +51,7 @@ SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
- **AI 不确定性处理**:主内容和资产拆开,图片/音频失败不阻塞阅读。
- **Provider 产品化**:用户看到稳定能力,系统内部用 Capability / Provider / Adapter / Routing Policy 管供应链。
- **可观测性**generation job/event 让生成过程、失败恢复和 Provider 成本可解释。
- **可继续生产化**前端已有轮询形态,后端已有任务事件模型,下一步可以迁移到 worker
- **可继续生产化**统一生成已经迁移到 worker前端轮询和任务事件模型也已打通下一步是补取消/重试队列和更完整监控
---
@@ -63,4 +63,4 @@ SMOKE_AUDIO=1 ./scripts/demo_smoke.sh
| 图片生成失败 | 展示 `degraded_completed` 与资源重试 |
| Docker 冷启动慢 | 演示前先跑 smoke 并保持容器运行 |
| Provider 追问过深 | 回到 Capability / Provider / Adapter / Routing Policy 四层解释 |
| 生产化追问 | 说明下一步是 worker 化、监控告警、密钥治理和 Provider analytics 扩展 |
| 生产化追问 | 说明下一步是取消/重试队列、监控告警、密钥治理和 Provider analytics 扩展 |

View File

@@ -83,4 +83,4 @@ AI 生成产品最大的问题不是“能不能调模型”,而是结果不
### 这个项目下一步怎么上线?
会先把当前轻量 job/event 模型迁移到后台 worker 和进度轮询,再补跨时间窗口的 provider 运营分析。生产上线前还需要补真实用户鉴权配置、密钥管理、监控告警和部署策略。
已经把当前轻量 job/event 模型迁移到后台 worker,并打通了前端进度轮询;下一步会补取消/重试队列,再继续扩展跨时间窗口和跨用户维度的 provider 运营分析。生产上线前还需要补真实用户鉴权配置、密钥管理、监控告警和部署策略。

View File

@@ -71,6 +71,7 @@ Week 2 已完成演示闭环、统一生成工作流、generation job/event、
| W4-08 | Ops | 任务运行概览与失败摘要 | `GET /api/generations/ops-summary` + 最近失败列表 | P1 | Done |
| W4-09 | Workflow | 卡住任务自动收敛 | `GENERATION_JOB_STALE_MINUTES` + Celery beat stale job maintenance | P1 | Done |
| W4-10 | Workflow | 防止重复资产任务 | 运行中故事拒绝重复封面/音频/资产重试请求 | P1 | Done |
| W4-11 | Workflow | 生成任务取消与重新排队 | 取消已提交任务,失败/取消任务可重新排队 | P1 | Done |
---

View File

@@ -18,6 +18,11 @@
- 时间线能展示阅读记录与记忆沉淀
- Week 4 已补齐绘本阅读位置恢复。
- Week 4 已输出架构说明和 Demo 包装文档。
- 生产化主线已继续推进:
- `POST /api/generations` 已迁移到后台 worker
- 创建弹窗会先拿到 `generation_job_id`,再轮询主记录落库
- 统一生成链路的 smoke、测试和前端构建已跟进到异步语义
- 首版取消/重试队列已落地,支持取消已提交任务和从失败/取消任务重新排队
---
@@ -43,7 +48,7 @@ DreamWeaver 已经具备求职演示所需的完整闭环:
最近一轮验证包括:
- 后端全量测试91 passed
- 后端全量测试94 passed
- 后端 ruff通过
- 用户端生产构建:通过
- 管理端生产构建:通过
@@ -56,10 +61,9 @@ DreamWeaver 已经具备求职演示所需的完整闭环:
| Priority | Task | Why |
| --- | --- | --- |
| P0 | 将同步生成迁移到 Celery worker | 支持真实长任务、断点恢复和后台进度 |
| P1 | 生成任务取消与重试队列 | 防止重复任务和用户误触造成浪费 |
| P1 | 跨用户 / 跨环境 Provider dashboard | 当前已支持单用户摘要,后续要支持运营视角 |
| P0 | 跨用户 / 跨环境 Provider dashboard | 当前已支持单用户摘要,后续要支持运营视角 |
| P1 | 监控告警与结构化 dashboard | 目前已有故事库级概览,后续要接入更完整观测体系 |
| P1 | 断点续跑与更细粒度任务控制 | 让取消、重试和 worker 恢复更稳 |
| P2 | 更细粒度叙事风格与音色策略 | 扩展体验,但不影响当前求职版主线 |
---

View File

@@ -68,21 +68,25 @@ DreamWeaver 当前同时支持普通故事生成、完整故事生成和绘本
- 已新增任务运行概览 `GET /api/generations/ops-summary`,故事库可展示最近失败、运行中任务和超时待收敛任务
- 重复资产任务已加入保护:同一故事存在运行中 job 时,不再重复触发封面、音频或统一资产重试
- Celery beat 已支持定时收敛卡住的 generation job避免任务长期停在 running
- 用户端与管理端生成轨迹组件会在任务未终止时自动轮询,为后续后台 worker 进度流保留前端形态
- 用户端与管理端生成轨迹组件会在任务未终止时自动轮询,已经可直接消费后台 worker 进度流
- `POST /api/generations` 响应已返回 `generation_job_id`smoke 脚本会验证 job 查询与 story job history
- 用户端与管理端的故事详情页、绘本阅读页已接入生成轨迹,展示生成/重试任务、关键事件、Provider 调用结果和聚合指标
- 故事详情页封面补全已切换到统一资产重试入口
- 管理端前端构建阻塞已修复,主前端与 admin 前端均可完成生产构建
- 已补首版生成任务控制能力:
- `POST /api/generations/jobs/{job_id}/cancel`
- `POST /api/generations/jobs/{job_id}/retry`
- 创建弹窗与生成轨迹都可触发取消或重新排队
### Remaining Production Work
- 普通故事、完整生成、绘本生成已有统一外部入口,内部 workflow 仍可继续减少兼容层分支
- 统一资产重试入口已覆盖普通故事封面、绘本缺失插图和故事音频,后续可继续扩展更细的资产级审计
- 后台异步 worker 执行、断点续跑、跨用户/跨环境 Provider 分析,以及真正的取消/重试队列仍属于后续生产化增强
- 断点续跑、跨用户/跨环境 Provider 分析,以及更细粒度的任务控制策略仍属于后续生产化增强
### What This Means
这份 PRD 仍然保留目标态设计,但主干能力已经可在当前代码中演示。当前最适合的继续方式,是继续把同步请求迁移到后台 worker把当前首版运营摘要扩展为可筛选、可对比的分析视角,而不是继续扩大功能范围。
这份 PRD 仍然保留目标态设计,但主干能力已经可在当前代码中演示。当前最适合的继续方式,是在已落地的 worker 化与任务控制基础上,把当前首版运营摘要扩展为可筛选、可对比的分析视角,并逐步补断点续跑和更完整监控,而不是继续扩大功能范围。
---
@@ -93,13 +97,13 @@ DreamWeaver 当前同时支持普通故事生成、完整故事生成和绘本
DreamWeaver 当前存在以下工作流层面问题:
1. **生成入口已建立,内部路径正在收束**
当前前端已切到 `/api/generations`,旧的 `/api/stories/generate``/api/stories/generate/full``/api/storybook/generate` 仍作为兼容入口保留。service 内部已抽取上下文准备、主记录保存、封面补全、绘本插图补全和音频补全 helper并用 `AssetCompletionResult` 表达资产补全结果。generation job/event 已落库并可查询Provider 调用轨迹、单故事聚合指标和跨故事运营摘要也已进入用户端与管理端展示。下一步重点是为后台异步 worker 复用这些事件
当前前端已切到 `/api/generations`,旧的 `/api/stories/generate``/api/stories/generate/full``/api/storybook/generate` 仍作为兼容入口保留。service 内部已抽取上下文准备、主记录保存、封面补全、绘本插图补全和音频补全 helper并用 `AssetCompletionResult` 表达资产补全结果。generation job/event 已落库并可查询Provider 调用轨迹、单故事聚合指标和跨故事运营摘要也已进入用户端与管理端展示;统一生成请求现在已经交给后台 worker 执行。下一步重点是把取消/重试队列也接到这套事件模型上
2. **保存与资产补全过程正在统一**
文本故事和绘本已拥有更清晰的主记录保存 helper普通故事封面、绘本缺失插图、故事音频生成/缓存已共用各自的 asset completion helper。服务层已经能表达资产任务结果并会把统一入口、资产重试、绘本逐页插图和音频生成的关键节点写入 job event。
3. **状态表达已基本统一,仍需生产化扩展**
当前已经能用 `generation_status``text_status``image_status``audio_status``retryable_assets` 表达生成中、部分可读、完成、降级完成、失败和可重试。后续重点是让后台 worker、运营分析和通知系统复用同一套状态语义。
当前已经能用 `generation_status``text_status``image_status``audio_status``retryable_assets` 表达生成中、部分可读、完成、降级完成、失败和可重试。后续重点是让取消请求、重新排队、运营分析和通知系统复用同一套状态语义。
4. **失败处理策略不统一**
图片、音频、绘本页生成失败时,系统没有统一的降级定义,用户体验和技术行为都不够稳定。

View File

@@ -100,8 +100,7 @@ flowchart LR
当前仍是求职版 MVP不引入复杂工作流引擎。下一步生产化优先级
1. 把同步生成迁移到后台 worker
2. 基于现有 job 查询和前端轮询展真实异步进度。
1. 补齐生成任务取消与重新排队能力,减少误触和重复消耗
2. 基于现有 job 查询和前端轮询继续扩展真实异步进度与任务控制
3. 扩展 Provider analytics 的时间窗口、失败原因和跨用户维度。
4. 为音频缓存增加过期策略和后台清理任务。
5. 补充部署、监控告警和密钥治理策略。
4. 继续补充部署、监控告警和密钥治理策略。

View File

@@ -6,7 +6,7 @@
已新增轻量 `generation_jobs``generation_job_events` 表,但不引入复杂工作流引擎。
原因是当前 MVP 的生成方式仍然以同步请求为主:后端在一次请求中完成主内容保存,再补全封面、绘本插图或语音。用户最关心的是“这个故事现在能不能读、哪些资产可补全”;系统侧则需要有足够的轨迹说明“这次生成做到了哪一步、哪里失败、哪些资产还能重试”。
原因是当前 MVP 已经进入“请求接收与后台执行分离”的阶段:`POST /api/generations` 先接受请求并返回 `generation_job_id`,再由 Celery worker 完成主内容保存和后续资产补全。用户最关心的是“这个故事现在能不能读、任务跑到哪一步、哪些资产可补全”;系统侧则需要有足够的轨迹说明“这次生成做到了哪一步、哪里失败、是否被取消、哪些资产还能重试”。
因此当前采用轻量落库策略:
@@ -43,22 +43,24 @@ job 响应会返回 `progress_percent`、`progress_label` 和 `is_terminal`
- 音频缓存由 `STORY_AUDIO_CACHE_TTL_DAYS` 控制过期时间Celery beat 会每日清理。
- 生成任务由 `GENERATION_JOB_STALE_MINUTES` 控制卡住阈值Celery beat 会每 30 分钟扫描一次,将超时运行中的任务标记为 `generation_stale_failed`
- 当某个故事已经有运行中的 job 时,封面补全、音频生成和统一资产重试会直接拒绝重复请求,避免用户连点造成重复成本。
- 统一生成请求已由 Celery worker 执行,前端会先拿到 `generation_job_id`,再轮询 job 详情直到主记录落库或任务终止。
- 当前已支持首版任务控制:队列中的任务可直接取消,运行中的任务可在安全检查点取消,失败或已取消任务可重新排队。
## 什么时候需要落库 job
## 什么当前仍然需要扩展 job 模型
如果续进入真实生产化,需要扩展当前 job/event 模型:
虽然 worker 化已经完成,但如果续进入真实生产化,仍然需要扩展当前 job/event 模型:
- 生成流程改成真正异步,前端需要轮询后台 worker 的实时进度
- 单个故事会产生多次生成尝试,需要对比每次任务的 provider 表现、重试原因和资产结果。
- 单个故事会产生多次生成尝试,需要对比每次任务的 provider 表现、取消原因、重试原因和资产结果
- 需要展示比当前事件更细颗粒度的步骤,例如 prompt 构建、provider 选择依据、provider failover 原因、每次调用 token/图片/语音成本。
- 需要按 provider、成本、延迟和失败原因做运营分析。
- 需要继续扩展取消与重试队列的颗粒度,例如更细的中断点、任务依赖和断点续跑策略。
- 需要断点续跑,避免 Worker 重启后丢失中间状态。
## 推荐未来扩展
当前已有两层记录,未来可以继续扩展字段和事件颗粒度:
- 将同步生成请求迁移到真正异步 worker 后,继续复用现有 job 查询和前端轮询进度条。
- 继续复用现有 job 查询和前端轮询进度条,为取消请求、重新排队和长任务通知提供统一入口
- 将当前跨故事 provider 指标扩展为跨用户、跨环境和更细颗粒度的失败原因维度分析。
## 面试表达