并发队列与 Lane 状态机实战:session/global 双层排队

并发队列与 Lane 状态机实战:session/global 双层排队

这一章把“并发控制”写成可复刻的状态机:同会话保序、全局限流、重启后可恢复。

入口(概念版):

对应源码入口(可选)

  • src/process/command-queue.ts
  • src/agents/pi-embedded-runner/lanes.ts
  • src/gateway/server-lanes.ts
  • src/agents/pi-embedded-runner/runs.ts

核心数据结构(你实现时建议显式保留)

  • LaneStatequeue / activeTaskIds / maxConcurrent / draining / generation
  • QueueEntryenqueuedAt / warnAfterMs / onWait(只告警,不取消)

关键流程(入队 → drain → 完成回收)

  1. 入队后立即触发 drain(不要等下一次事件)。
  2. draining 防重入,避免并发 pump 造成重复拉起。
  3. 失败分支也要继续 pump(否则队列会饿死/僵死)。

reset/generation(重启后不僵死的关键)

in-process 重启或异常中断时,旧任务的 finally 可能不会执行。 generation 的作用是:旧回调回写时发现 generation 不匹配,就忽略写回,避免污染新状态。

失败场景与排障入口

  • 同会话乱序:确认是否有 session lane 串行,以及 maxConcurrent 是否被意外改大。
  • 队列卡死:检查失败分支是否继续 pump;检查是否因重入导致 draining 永久为 true。
  • probe lane 日志轰炸:探针任务失败应静默,避免误导性噪音。

验收清单

  1. 同一 session 连发多条消息,回复顺序稳定。
  2. 两个 session 可并发执行,不互相阻塞。
  3. reset 后积压任务能继续 drain(不僵死)。