2026-05-30 22:42:23 +08:00
|
|
|
|
# 异步任务 — 队列与调度
|
|
|
|
|
|
|
|
|
|
|
|
FIFO 串行执行,信号驱动调度
|
|
|
|
|
|
|
2026-05-30 23:13:23 +08:00
|
|
|
|
<div class="grid grid-cols-2 gap-4 mt-2">
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
2026-05-30 22:42:23 +08:00
|
|
|
|
|
|
|
|
|
|
```go {1-6|8-12|all}
|
|
|
|
|
|
type TaskQueue struct {
|
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
|
jobs []*TaskJob
|
|
|
|
|
|
ready chan struct{} // 新任务到达信号
|
|
|
|
|
|
stop chan struct{} // 优雅关闭信号
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (q *TaskQueue) Enqueue(job *TaskJob) {
|
|
|
|
|
|
q.mu.Lock()
|
|
|
|
|
|
q.jobs = append(q.jobs, job)
|
|
|
|
|
|
q.mu.Unlock()
|
|
|
|
|
|
q.ready <- struct{}{} // 唤醒 run() 协程
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-30 23:13:23 +08:00
|
|
|
|
<div class="flex flex-col justify-center">
|
|
|
|
|
|
|
2026-05-30 22:42:23 +08:00
|
|
|
|
<v-clicks>
|
|
|
|
|
|
|
|
|
|
|
|
<Item title="Enqueue → run() → processNext() 流程">
|
|
|
|
|
|
提交任务入队并发送信号。`run()` 协程阻塞等待信号,收到后调用 `processNext()` 取队首任务执行。FIFO 保证任务按提交顺序串行处理。
|
|
|
|
|
|
</Item>
|
|
|
|
|
|
|
|
|
|
|
|
<Item title="每个 Job 是一个闭包">
|
|
|
|
|
|
`TaskJob` 封装了 `context.Context` 和执行函数。闭包捕获任务参数,context 控制超时和取消,确保每个任务独立且可中断。
|
|
|
|
|
|
</Item>
|
|
|
|
|
|
|
|
|
|
|
|
</v-clicks>
|
|
|
|
|
|
|
2026-05-30 23:13:23 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-05-30 22:42:23 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 进度推送与 WebSocket
|
|
|
|
|
|
|
|
|
|
|
|
Context 注入 + 多通道推送
|
|
|
|
|
|
|
|
|
|
|
|
```go {1-3|5-8|all}
|
|
|
|
|
|
func WithProgressReporter(ctx context.Context, r ProgressReporter) context.Context {
|
|
|
|
|
|
return context.WithValue(ctx, progressCtxKey, r)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 管线节点中使用
|
|
|
|
|
|
reporter := GetProgressReporter(ctx)
|
|
|
|
|
|
reporter.Report(Progress{Stage: "prompt", Percent: 25})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-31 00:01:33 +08:00
|
|
|
|
---
|
2026-05-30 22:42:23 +08:00
|
|
|
|
|
2026-05-31 00:01:33 +08:00
|
|
|
|
# 进度推送 — 阶段与通道
|
2026-05-30 23:13:23 +08:00
|
|
|
|
|
2026-05-30 22:42:23 +08:00
|
|
|
|
<v-clicks>
|
|
|
|
|
|
|
|
|
|
|
|
<Item title="进度阶段划分">
|
|
|
|
|
|
5%(任务创建)→ 25%(提示词优化完成)→ 60%(素材生成完成)→ 80%(质检通过)→ 100%(格式适配 + 上传)。每个阶段由对应节点触发回调。
|
|
|
|
|
|
</Item>
|
|
|
|
|
|
|
|
|
|
|
|
<Item title="双通道推送">
|
|
|
|
|
|
**WebSocket**:`ws://host/api/v1/tasks/:taskId/ws`,实时推送进度和结果。**HTTP 轮询**:`GET /api/v1/tasks/:taskId`,兼容降级方案。
|
|
|
|
|
|
</Item>
|
|
|
|
|
|
|
|
|
|
|
|
</v-clicks>
|
|
|
|
|
|
|
2026-05-31 00:01:33 +08:00
|
|
|
|
<div class="flex justify-center mt-2">
|
|
|
|
|
|
<img src="../public/async-task.svg" class="w-full max-h-[200px] object-contain" />
|
2026-05-30 22:42:23 +08:00
|
|
|
|
</div>
|