JianFeeeee
d9c2e51f61
fix(agent): cancel 停不下调度循环 —— 队列非空时永远不看 ctx.Done
## 缺陷(真缺陷,不是测试问题)
`schedulerLoop` 只在"队列空"的分支里 select `ctx.Done()`:
if kind == nextNone {
select { ... case <-a.ctx.Done(): return }
}
于是**只要队列里有任务,循环就永远不看 ctx.Done** —— 一直取、一直执行,
直到队列被取空才可能退出。
生产后果(`reclaim` / `destroy`):销毁流程先回收残余任务、再销毁子。
而回收到销毁之间子仍在运行,继续把队列里的任务取走执行 —— 那些任务的
结果**永远无人认领**(子随即被销毁),且日志无痕迹:既不在"残余清单"里,
也没跑到出结果。带 ResponseCh 的同步调用方(cli/a2a)更糟:Stop 的
drainPendingInterrupts 给它补一个 "skipped",用户看到"已跳过",
而任务其实执行过。
## 修法
1. `schedulerLoop` 循环顶部(**取任务之前**)检查 ctx.Done。
2. 新增 `waitSchedulerStopped`:cancel 之后等 running 归零(上限 5s,
超时如实记日志,不让控制面永久挂住)。
3. 新增 `FinishResident`:停止调度 → 回收残余 → 处置 → 收割记忆 → 销毁,
**一步完成**,消除"取完到销毁"之间的窗口。`reclaim` / `destroy` 改走它。
4. 记忆收割抽成 `harvestResidentMemory`,供 FinishResident 的 onDestroy 复用
(必须在 Destroy 之前 —— Destroy 会关掉 temp)。
## 判据(2 条,都做了"撤销修复必须变红"的验证)
· TestSchedulerStopsTakingTasksAfterCancelWithNonEmptyQueue
用阻塞 provider 把循环钉在 executeNewTask 里,此时塞 5 条进队列、
cancel、放行。修复在位 ⇒ 5 条一条都不执行;撤销修复 ⇒ 取走 5 条。
**实测撤销后报「仍取走了 5 条(剩 0/5)」,恢复后 10/10 绿。**
· TestFinishResidentIsAtomic
断言返回后子已从登记表移除(销毁确实在同一事务内完成)。
原 flaky 的 TestResidualKeepReturnsTasksToParent 与
TestResidualDropNotifiesSyncCaller 也修了:先 cancel + 等静止再入队,
得到确定的初始状态(它们验的是转交逻辑,不是子的生命周期)。30/30 绿。
## 我踩过的两条弯路(都写进判据注释了)
1. 加 `scheduler.freeze` 绕过。错在:调度器本来就有停止语义(ctx),
再引入一个状态位会让"谁负责停"含糊,且忘了解除就永久僵住。已删。
2. 判据第一版写成「先 Start、再 cancel、然后入队」—— 那时队列是**空的**,
循环正好走 nextNone 看到 ctx.Done 退出,于是**撤掉产品修复判据依然
30/30 全绿**。是用户追问"凭什么说修好了"才发现这是假绿。
必须造出"队列非空时 cancel"这个确切场景才测得到。
2026-10-18 13:07:40 +08:00
..
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-12 14:26:13 +08:00
2026-10-12 10:13:36 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-12 14:26:13 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-12 14:26:13 +08:00
2026-10-12 14:26:13 +08:00
2026-10-17 19:18:24 +08:00
2026-10-12 14:26:13 +08:00
2026-10-12 10:13:36 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 13:07:40 +08:00
2026-10-18 10:16:53 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-09-19 16:49:16 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-09-27 11:55:33 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-06 09:22:12 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 13:07:40 +08:00
2026-10-18 13:07:40 +08:00
2026-10-18 13:07:40 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-09-13 08:59:15 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-09-13 07:00:51 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 13:07:40 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:53 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:53 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-17 19:18:24 +08:00
2026-09-17 18:56:15 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 06:38:51 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-13 16:18:13 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 06:38:51 +08:00
2026-10-18 06:38:51 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-05 11:25:20 +08:00
2026-10-17 19:18:24 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-08 10:40:17 +08:00
2026-10-18 06:38:51 +08:00