Files
gen2d/docs/async-tasks.md
wonder 0847d126a2 fix: 任务创建后直接进入 running 状态,避免前端显示排队中
- 移除任务初始状态 pending,改为直接创建为 running
- 初始进度设为 5%,stage 设为 prompt_builder
- 更新文档以反映实际执行流程(无队列机制)
- 修复前端轮询时因竞态条件显示排队中的问题
2026-05-25 18:16:21 +08:00

132 lines
4.6 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 异步任务
## 概述
生成任务采用「提交-异步执行-轮询/推送」模式:API 同步返回 taskId,后端异步执行四阶段管线,前端通过轮询或 WebSocket 获取进度与结果。
## 任务生命周期
```mermaid
stateDiagram-v2
[*] --> running : POST /api/v1/generate
running --> completed : 四阶段全部通过
running --> failed : 节点执行失败 / 超过重试次数
completed --> [*]
failed --> [*]
```
| 状态 | 说明 | 持久化 |
|------|------|--------|
| `running` | 管线执行中,`task.stage` 记录当前阶段 | `task.status = 'running'`, `task.stage`, `task.progress` |
| `completed` | 管线完成,素材已保存到本地 | `task.status = 'completed'`, 写入 `asset` 表 |
| `failed` | 执行失败或超过重试上限 | `task.status = 'failed'`, `task.error` 记录原因 |
| `saving` | 保存素材中(内部状态) | `task.status = 'saving'` |
## 任务执行
各任务独立通过 goroutine 异步执行,无队列机制:
### 提交流程
```
POST /api/v1/generate
│
├── 1. 创建任务记录(status=running, stage=prompt_builder, progress=5)
├── 2. 同步返回 taskId
└── 3. 后台 goroutine 执行管线
```
### 执行流程
```
后台 goroutine 执行 RunPipeline(ctx, input)
│
├── 1. 查询 task + project_style
├── 2. 构造 PipelineInput
├── 3. 执行管线,实时更新 stage & progress
│ ├── prompt_builder → stage 更新,progress 5-25%
│ ├── asset_generator → stage 更新,progress 25-60%
│ ├── quality_supervisor → stage 更新,progress 60-80%(可能触发重优化分支)
│ └── format_adapter → stage 更新,progress 80-90%
├── 4. 上传素材至存储并写入 asset 表(status=saving, progress 90%)
├── 5. 更新 task.status = completed(progress 100%)
└── 6. 异常时更新 task.status = failed, task.error = 错误信息
```
### 并发控制
无固定 Worker 限制,每个请求启动一个独立 goroutine。实际并发受:
- 系统资源(CPU、内存)
- AI 推理 API 限流
- 数据库连接池
## 管线阶段与进度
每个阶段对应 Eino Graph 的一个节点,执行过程中更新 `task.stage` 和 `task.progress`:
| 阶段 | stage 值 | 进度范围 | 说明 |
|------|----------|---------|------|
| 提示词优化 | `prompt_builder` | 5-25% | 调用 PromptAgent/LLM 优化提示词,合并风格与技术参数 |
| 素材生成 | `asset_generator` | 25-60% | 调用 AI 推理 API 出图 |
| 质量检查 | `quality_supervisor` | 60-80% | 视觉模型质检 |
| 格式适配 | `format_adapter` | 80-100% | 格式转换、spritesheet 打包、保存素材 |
进度更新通过 WebSocket 实时推送给前端(参见 [API 设计 - WebSocket 消息格式](api.md))。
## 重试策略
### 质检重试(管线内重试)
QualitySupervisor 质检不通过时,Eino Graph 分支回到 PromptOptimizer 重新优化提示词:
```
QualitySupervisor -- fail --> PromptOptimizer --> AssetGenerator --> QualitySupervisor
QualitySupervisor -- pass --> FormatAdapter
```
| 参数 | 默认值 | 说明 |
|------|--------|------|
| 最大重试次数 | 3 | `task.retry_count` 达到上限后降级输出 |
| 重试触发条件 | 质检不通过 | 视觉模型判定风格不一致 |
超过重试次数后,跳过质检直接进入 FormatAdapter 输出(降级策略,保证任务不会无限循环)。
### 任务级重试(管线外重试)
管线执行过程中发生不可恢复的错误(如 AI API 超时、文件写入失败):
| 参数 | 默认值 | 说明 |
|------|--------|------|
| 最大重试次数 | 1 | 仅重试一次 |
| 重试间隔 | 5 秒 | 固定间隔 |
重试时重新执行完整管线,不保留上次中间状态。
## 进度推送
前端可通过两种方式获取任务进度:
### 轮询
```
GET /api/v1/tasks/:taskId
```
前端定时调用(建议间隔 2-3 秒),简单可靠,适合不需要实时性的场景。
### WebSocket
```
ws://host/api/v1/tasks/:taskId/ws
```
长连接实时推送,通过 httpOnly Cookie 自动认证,每个阶段的状态变更立即通知前端。消息格式参见 [API 设计](api.md)。
## 去重
去重策略详见 [数据存储 — 去重策略](database.md#去重策略)。相同输入的并发请求直接返回已有 taskId,任务完成后从内存清除。
## 文件存储
任务完成后,FormatAdapter 将素材保存到本地文件系统。素材文件的存储结构与访问方式详见 [数据存储 — 文件存储](database.md#文件存储)。