Skip to content

kernel: run 结算持久化失败后 activeRun 永久泄漏,内核拒绝后续所有运行 #165

Description

@RXQ6

问题

RunManager.execute()结算段不在任何 try/catch 保护范围内。一旦结算期间任一存储写入抛错(例如 JSON 文件损坏触发 STORAGE_WRITE_FAILED——仓库近期刚修过组合文件损坏 #147,说明这是现实场景),execute 的 promise 会以 unhandled rejection 失败,this.activeRun 永远不会被清空。

后果是进程级死锁:

  • isRunning() 从此恒为 true,之后每一次 startRun 都被 RUN_IN_PROGRESS 拒绝,直到重启;
  • 事件订阅者收不到任何终端事件(eval harness 等待方会一直挂到超时);
  • run 记录永远停留在 running

当前现状

代码审查基线:039c7388f855ab85f9882300c16b1898fe5955bb

  • packages/shared/src/kernel/run-manager.ts:287void this.execute(run, ...) fire-and-forget,无 .catch
  • 行 352–354 的 catch 只覆盖 ensureSession + 事件循环消费;
  • 行 356–428 的结算代码(runs.updateappendMessageupdateSessionclearWallClockTimerthis.activeRun = null、终端事件合成)全部在 try 之外,其中任何一个 await 抛错都会绕过所有清理逻辑。

期待的解决方向

  1. 结算持久化(run 记录、assistant message、session 状态)降级为尽力而为:单个写入失败不阻断其余清理;
  2. 无论持久化成败,clearWallClockTimerthis.activeRun = null 与终端事件合成必须发生——订阅者总能观察到 run_completed/run_failed
  3. 补充测试覆盖"结算写入失败"场景。

验证标准

  • 结算写入抛错时 isRunning() 恢复 false,终端事件仍被广播;
  • 失败后再次 startRun 不再被 RUN_IN_PROGRESS 拒绝;
  • 不产生 unhandled rejection;
  • 现有 kernel 测试全绿。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions