问题描述
文件: frontend/src/features/workflow-controller/controller.ts:762-797
restartFromNode 函数中:
const restarted = await persist((run) => { // ← 在序列化队列内执行
const resetNodes = run.nodes.map((node) =>
affectedIds.has(node.id) ? resetNode(node) : node,
)
return { ...run, nodes: normalizeAvailability(resetNodes) }
})
for (const affectedId of affectedIds) {
nodeEpochs.set(affectedId, nodeEpoch(affectedId) + 1) // ← 在队列外执行
}
persist 通过 enqueue 序列化执行,但 epoch 递增在 persist resolve 之后、队列外执行。submitGeneration 在第 513 行读取 epoch 时也在队列外。
虽然 JS 单线程模型下同步的 epoch 递增不太可能被抢占,但 epoch 与节点状态的更新不是原子的——如果 persist 和 epoch 递增之间有异步操作介入(如 microtask),可能出现 epoch 已递增但节点状态尚未更新的窗口。
建议修复
将 epoch 递增移入 persist 回调内部,或在 persist 完成后、epoch 递增前加锁/禁用提交。
影响
- 严重程度: Low-Medium
- 极端时序下节点状态与 epoch 不一致
问题描述
文件:
frontend/src/features/workflow-controller/controller.ts:762-797restartFromNode函数中:persist通过enqueue序列化执行,但 epoch 递增在persistresolve 之后、队列外执行。submitGeneration在第 513 行读取 epoch 时也在队列外。虽然 JS 单线程模型下同步的 epoch 递增不太可能被抢占,但 epoch 与节点状态的更新不是原子的——如果
persist和 epoch 递增之间有异步操作介入(如 microtask),可能出现 epoch 已递增但节点状态尚未更新的窗口。建议修复
将 epoch 递增移入
persist回调内部,或在persist完成后、epoch 递增前加锁/禁用提交。影响