Skip to content

fix(orca): worker 切换不再同步等待冷启动 - #5205

Open
zyjisdog wants to merge 7 commits into
makecindy:mainfrom
zyjisdog:fix/orca-focus-async-resume
Open

zyjisdog wants to merge 7 commits into
makecindy:mainfrom
zyjisdog:fix/orca-focus-async-resume

Conversation

@zyjisdog

@zyjisdog zyjisdog commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

协同模式下首次切到 dormant worker 要等 5s:switch_focus 的 IPC / MCP handler 里同步 await 冷会话的 resume,而冷会话要 spawn 整个 agent runtime(Pi 实测 23s,含 11 个 MCP server + resume 会话),renderer 的面板切换要等这条 IPC 返回才发生。第二次切换快,是因为 runtime 已经 live,resumeOrcaWorkerSessionIfMissing 首行 maker.getSession 命中即返回。

本次把 idle worker 的 runtime 预热转后台:switch_focus 在 setWorkerFocus + 广播后立即返回;新增 orcaWorkerResumeScheduler 做 per-session 去重并复用 sendToSession 的 per-session 锁,承接 focus 预热与派活路径的 resume,保证同一会话不会被并发 bootstrap 两次(发送先持锁完成懒恢复时,后台 resume 在锁内重查 live 并跳过)。worker 历史来自 DB,展示不需要 live runtime;发送/派活路径本来就有懒恢复,冷启成本从「阻塞切换」移到「后台预热」。

变更类型

  • fix 缺陷修复

范围

  • 关联 Issue / 需求:用户实报(协同模式下首次切换到不同 worker 卡 ~5s+,第二次很快)
  • 本 PR 包含:
    • switch_focus(IPC + MCP)改为后台调度 resume,focus 不再等待冷启动
    • 新增 orcaWorkerResumeScheduler(per-session 去重 + 与 withSendToSessionLock 共用锁),派活路径 resumeWorkerSession 同样接入
    • 更新 docs/dev-rules/orca-team-architecture.md Worker 运行态不变量
    • 后台预热可取消:关闭协同 / 归档 / 显式 idle 释放 runtime 前先取消未落地的唤醒;bootstrapSession 返回后复核会话仍 active,失效则关掉刚拉起的 runtime
    • 调度器单测 + source-contract 断言更新
  • 明确不包含:不做 renderer 乐观切换;不改 worker 生命周期 / idle 释放语义;不改模型切换路径
  • 用户可见变化:首次切到休眠 worker 时面板立即切换,runtime 在后台启动
  • 是否存在 breaking change:无

UI 变化

  • 引用的设计规范:不涉及(无视觉 / 交互 / 文案变化,仅切换时机变快)

怎么验证的

自动验证

pnpm --filter desktop run typecheck
结果:exit 0

PATH="/c/Users/veget/.cargo/bin:/c/Windows/System32:$PATH" pnpm test:unit:related
结果:exit 0(apps/desktop unit related PASS,含新增调度器用例)

新增 apps/desktop/src/main/maker-ipc/__tests__/orcaWorkerResumeScheduler.test.ts
8 例(per-session 去重 / 锁内执行 / 多会话互不耦合 / 后台失败可重试 / cancel 三例 / 无 in-flight no-op):全过

pnpm check:dco
结果:通过(功能 commit 已签名;merge commit 依仓库规则豁免)

手工验证

  • pnpm restart:desktop:remote --region=cn(commit 2b37adf65)启动 dev 实例成功:DESKTOP_DEV_VERDICT=ready。

未执行的验证

  • 首次切换的运行时交互实测未完成:dev 实例 smoke 启动成功,但实例在交互测试前退出(未复现);发版前建议在含本 commit 的构建里补验一次「首次切 dormant worker 面板不等待」。
  • guard tier 的 makerSendToSessionOrdering.test.ts 存在 upstream 自身的 source-contract 漂移(源码已是 pendingAgentSwitchApplyHolder = async (sessionId, signal, selection, beforeApply) =>,断言仍按旧签名匹配),与本 PR 无关;该 tier 不在 unit CI 路径内,upstream main CI 绿。本 PR 对该文件的改动只是其中的 switch_focus 断言。

风险

风险分类

  • 其他:协同 worker 运行态调度(无 schema / migration / 协议 / 权限变化)

影响与回滚

  • 影响范围:仅 Orca「协同」的 worker focus 切换与派活 warm-up 路径;worker 历史展示、发送懒恢复、idle 释放语义不变。
  • 回滚 / 降级方式:revert 本 PR 即可,回到「focus 同步等待冷启动」的旧行为。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s)
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI)
  • 未提交凭证、令牌或授权文件
  • 已核对受影响的文档(docs/dev-rules/orca-team-architecture.md 已同步新增不变量 3a)
  • 已确认测试结果或说明未执行原因

首次切到 dormant worker 要等 ~5s:switch_focus 的 IPC/MCP handler 同步 await
resumeOrcaWorkerSessionIfMissing,而冷会话要 spawn 整个 agent runtime(Pi 实测
2~3s,含 11 个 MCP server + resume 会话),renderer 的面板切换因此被阻塞。

- switch_focus(IPC 与 MCP)改为 setWorkerFocus + 广播后立即返回,idle worker 的
  runtime 预热转后台;worker 历史来自 DB,不需要 live runtime
- 新增 orcaWorkerResumeScheduler:per-session 去重 + 与发送路径共用 sendToSession
  锁,避免 focus 预热与发送/派活并发双 bootstrap
- resumeWorkerSession(派活路径)改走同一调度器;预热失败只告警,不影响 focus 结果
- 更新 orca 架构文档不变量;补调度器单测并同步 source-contract 断言

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
…c-resume

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
@zyjisdog
zyjisdog requested a review from a team as a code owner September 28, 2026 15:16
@greptile-apps

greptile-apps Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Changes worker resume to run in background instead of blocking focus switches.

就本次审查发现而言,该 PR 可以合并。

Summary

本 PR 将休眠 Worker 的 focus 预热改为后台调度,使面板切换不再等待冷启动;同时为预热增加去重、共用会话锁和取消后的清理,并补充运行期行为测试。

  • 新增测试覆盖授权失效、取消及会话归档后的 runtime 清理。
  • 本轮未发现由上次审查后改动引入的可报告问题。
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[switch_focus] --> B[设置 focus 并广播]
  B --> C[立即返回]
  B --> D[后台预热请求]
  E[派活请求] --> D
  D --> F[按会话去重并获取发送锁]
  F --> G{仍可恢复?}
  G -- 是 --> H[启动或复用 runtime]
  G -- 否 --> I[跳过或清理 runtime]
Loading

Reviews (6) · Last reviewed commit: "test(orca): 补 worker 唤醒清理的行为测试"

Comment thread apps/desktop/src/main/maker-ipc/register.ts
review P1:关闭协同 / 归档 / 显式 idle 释放 runtime 后,仍在等锁或冷启动中的
focus 预热会把已归档 worker 重新拉活。

- orcaWorkerResumeScheduler 增加 cancel:等锁中的唤醒直接放弃;已在冷启动的按
  isCancelled 在 bootstrap 返回后关掉刚起的 session
- resumeOrcaWorkerSessionIfMissing 冷启动前与 bootstrap 后都复核会话仍为 active,
  失效则跳过/关闭,fail-closed
- disableOrcaInternal(end team)与 OrcaTeamService 的 archiveWorker / idleWorker
  释放前先取消待执行唤醒
- 补调度器 cancel 单测与 source-contract 断言;同步架构文档不变量 3a

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
@zyjisdog

Copy link
Copy Markdown
Contributor Author

@greptileai review

@MagicLizi

Copy link
Copy Markdown
Contributor

维护者确认请求:本 PR 命中 rules(审查规则文档变更) 与 arch(核心路径改动 452 行) 两类确认触发,自动流程在维护者确认前不会合并。

需要确认的点:

  1. docs/dev-rules/orca-team-architecture.md 新增不变量 3a(审查判据自身的语义变更);
  2. apps/desktop/src/main/maker-ipc/ 核心路径改动(新增 orcaWorkerResumeScheduler、OrcaTeamServiceDeps.cancelWorkerResume 钩子、switch_focus 改为后台调度 resume)。

请维护者直接在本 PR 上 Approve 确认;需要作者修改则 Request Changes 并写明要求。详见讨论 issue:#5210

@MagicLizi MagicLizi added awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Sep 28, 2026
zyjisdog added a commit to zyjisdog/cindy that referenced this pull request Sep 28, 2026
Upstream-PR: makecindy#5205
Upstream-PR-Head: a816525
Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
zyjisdog added a commit to zyjisdog/cindy that referenced this pull request Sep 29, 2026
Upstream-PR: makecindy#5205
Upstream-PR-Head: a816525
Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
…c-resume

冲突解决:register.ts(resume helper 签名、MCP switchFocus 调度)与 orcaTeamService.ts
(idleWorker 的 assertAfterIdle)。上游新增 assertCurrent 插件权威校验,与本 PR 的
isCancelled 取消语义正交,合并保留两者:MCP switchFocus 仍透传 assertCurrent 到后台预热。

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
@zyjisdog

zyjisdog commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread apps/desktop/src/main/maker-ipc/register.ts Outdated
合并上游 assertCurrent(插件 authority / 账号边界)后暴露的缝隙:bootstrapSession
已创建 runtime,随后 assertCurrent() 抛错会直接冒泡,跳过原有关闭分支;后台预热只
记日志,刚启动的 worker 留在运行态。

- post-bootstrap 的授权复核包进 try/catch:失败先 closeSession 再原样抛出,保持同步
  调用方的冒泡语义,同时不让 runtime 泄漏
- 抽出 closeResumedSession(reason) 统一清理路径(授权失效 / 取消 / 已归档共用)
- source-contract 断言锁定「先清理再抛出」的顺序

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
@zyjisdog

zyjisdog commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread apps/desktop/src/main/__tests__/makerSendToSessionOrdering.test.ts
zyjisdog added a commit to zyjisdog/cindy that referenced this pull request Oct 1, 2026
Upstream-PR: makecindy#5205
Upstream-PR-Head: de22e05
Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
上一轮只加了 source-contract 文本断言(toContain + expectOrder),守不住运行期行为:
如果 post-bootstrap 的关闭分支将来真的不再关 runtime,文本断言仍会通过。
- 新增 orcaWorkerResumeCleanup.test.ts:沿用仓库既有的「切源码 + new Function 注入依赖」
  手法,真实执行 resumeOrcaWorkerSessionIfMissing
- 覆盖四条路径:授权复核在 bootstrap 后失效(关 session 且原错误继续抛)、取消标记在
  bootstrap 后为真(关 session 返回 false)、会话在冷启动过程中被归档(关 session)、
  健康路径(保留 runtime)
- 已做 mutation 验证:分别删掉两条 closeSession 调用,对应用例立刻失败
Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
@zyjisdog

zyjisdog commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai review

@MagicLizi MagicLizi added the touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) label Oct 1, 2026
@zyjisdog zyjisdog closed this Oct 2, 2026
@zyjisdog zyjisdog reopened this Oct 2, 2026
…c-resume

Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>

# Conflicts:
#	apps/desktop/src/main/__tests__/makerSendToSessionOrdering.test.ts
zyjisdog added a commit to zyjisdog/cindy that referenced this pull request Oct 5, 2026
Upstream-PR: makecindy#5205
Upstream-PR-Head: 650e4f2
Signed-off-by: Zhang Yunjin <zhangyunjin@zju.edu.cn>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants