fix(history): 历史运行复盘读库持久化 —— 杜绝过 Redis TTL 后卡「流式中…」
问题:历史任务超 Redis 流 10min TTL 后,SSE 回放在空流上永久阻塞 → 运行页卡「流式中…」、
轨迹/工具/输出全空。
修复:收尾把最终输出 + 执行轨迹持久化到 PG,历史复盘改读库(不依赖 Redis TTL):
- store:Task 加 output/trace 两列;SaveTaskOutput/SaveTaskTrace/GetRunDetail。
trace 用 type:text(不是 jsonb)——否则提交时空串 "" 入 jsonb 列会 INSERT 失败、整条任务不落库。
(已 ALTER 既有 trace 列 jsonb→text。)
- gateway:token/exec 录制器在 done 时把累计的输出/轨迹快照落库。
- 新增 GET /tasks/:id/replay 返回持久化的 {output, exec}。
- RunsView:选中历史运行改 runReplay() 读库(秒回、phase 立即 done/error),不再 SSE 回放。
即便旧任务无持久化数据,也是 done+空态,绝不再卡「流式中…」。
live:新任务落库 output 305 字(含表格) + 轨迹 5 事件,/replay 正确返回;tsc+vite、gateway 全绿。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -145,6 +145,34 @@ func (p *Postgres) GetTaskStatus(ctx context.Context, id string) (status, detail
|
||||
return t.Status, t.Detail
|
||||
}
|
||||
|
||||
// SaveTaskOutput 收尾时落库最终模型输出(供历史复盘,best-effort)。
|
||||
func (p *Postgres) SaveTaskOutput(ctx context.Context, id, output string) error {
|
||||
if p.db == nil {
|
||||
return nil
|
||||
}
|
||||
return p.db.WithContext(ctx).Model(&Task{}).Where("task_id = ?", id).Update("output", output).Error
|
||||
}
|
||||
|
||||
// SaveTaskTrace 收尾时落库执行轨迹 JSON(供历史复盘,best-effort)。
|
||||
func (p *Postgres) SaveTaskTrace(ctx context.Context, id, traceJSON string) error {
|
||||
if p.db == nil {
|
||||
return nil
|
||||
}
|
||||
return p.db.WithContext(ctx).Model(&Task{}).Where("task_id = ?", id).Update("trace", traceJSON).Error
|
||||
}
|
||||
|
||||
// GetRunDetail 取一条任务持久化的输出 + 轨迹(历史复盘读库,不依赖 Redis TTL)。
|
||||
func (p *Postgres) GetRunDetail(ctx context.Context, id string) (output, trace string) {
|
||||
if p.db == nil {
|
||||
return "", ""
|
||||
}
|
||||
var t Task
|
||||
if err := p.db.WithContext(ctx).Select("output", "trace").Where("task_id = ?", id).First(&t).Error; err != nil {
|
||||
return "", ""
|
||||
}
|
||||
return t.Output, t.Trace
|
||||
}
|
||||
|
||||
// SaveEval 落库一条评测结果(按 task_id upsert:重评覆盖)。
|
||||
func (p *Postgres) SaveEval(ctx context.Context, e *Eval) error {
|
||||
if p.db == nil {
|
||||
|
||||
Reference in New Issue
Block a user