fix(store): reconcileInterrupted 跳过已终态任务,避免 cancelled→failed 让 daemon 启动崩溃
执行中的任务被 cancel 后仍挂 started run;daemon 重启时 reconcileInterrupted 对它调 failTaskAttempt → transition(cancelled→failed) 非法 → 启动抛错退出(整个 daemon 起不来)。修:终态(cancelled/done)任务只 finishRun 收尾,不再 fail*Attempt。含回归测试(202 全绿)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-3
@@ -749,9 +749,17 @@ export class Store {
|
||||
let readopted = 0, reclaimed = 0;
|
||||
for (const { task, run } of this.liveRunsWithTask()) {
|
||||
if (isAlive(run)) { readopted++; continue; } // worker 仍活 → re-adopt,daemon 续 ingest
|
||||
if (run.kind === 'executor') this.failTaskAttempt(task.id, run.id, 'daemon 重启时发现 worker 已退出');
|
||||
else if (run.kind === 'planner') this.failPlanAttempt(task.id, run.id, 'daemon 重启时发现 planner worker 已退出');
|
||||
else this.finishRun(run.id, 'failed', { error: 'daemon 重启中断' }); // 残留复审 run:仅收尾
|
||||
// 任务已终态(如执行中被 cancel):只收尾残留 run,绝不再 fail*Attempt——
|
||||
// cancelled→failed 等非法流转会在 reconcile 中抛错、让 daemon 启动直接崩溃。
|
||||
if (task.status === 'cancelled' || task.status === 'done') {
|
||||
this.finishRun(run.id, 'failed', { error: 'daemon 重启时发现 worker 已退出(任务已终态,仅收尾不改任务状态)' });
|
||||
} else if (run.kind === 'executor') {
|
||||
this.failTaskAttempt(task.id, run.id, 'daemon 重启时发现 worker 已退出');
|
||||
} else if (run.kind === 'planner') {
|
||||
this.failPlanAttempt(task.id, run.id, 'daemon 重启时发现 planner worker 已退出');
|
||||
} else {
|
||||
this.finishRun(run.id, 'failed', { error: 'daemon 重启中断' }); // 残留复审 run:仅收尾
|
||||
}
|
||||
reclaimed++;
|
||||
}
|
||||
return { readopted, reclaimed };
|
||||
|
||||
Reference in New Issue
Block a user