合成退出后的延迟守护进程输出¶
守护进程的停止响应可能在其最终 DATA 和 EXIT 事件通过独立的流套接字到达之前,先通过其控制套接字到达。随后主进程会发出一个合成退出。延迟到达的 DATA 会重新创建一个无头模型,并将运行时 PTY 标记为已连接;旧的重复退出检查会在运行时清理之前抑制物理 EXIT。主机没有活动会话,但主进程仍保留连接记录、标题跟踪器和无头终端。
复现¶
从检出目录开始,使用其已安装的依赖项:
ORCA_BACKGROUND_LAUNCH=1 node docs/audits/daemon-late-exit/reproduce.mjs /tmp/daemon-late-exit-results.json
ORCA_BACKGROUND_LAUNCH=1 node node_modules/vitest/vitest.mjs run --config config/vitest.config.ts src/main/ipc/pty/daemon-late-exit.test.ts
该脚本使用真实的守护进程服务器、客户端、提供者、套接字对、kill IPC 处理器、监听器绑定和运行时。原生子进程边界是一个测试夹具,其强制终止回调会报告退出。仅暂停流读取器可使独立控制/流顺序变得确定。不会启动渲染器或可见应用。临时 Vitest 文件随后会被删除。
修复前用例仅在已加载模块中将重复抑制移回运行时清理之前。它保留当前感知 incarnation 的标记表示,这不会影响同一 incarnation 的竞争。磁盘上的源保持不变。脚本会验证其转换边界并记录当前源哈希。
结果¶
results.json 包含四个修复前/修复后对照:
| 场景 | 修复前 | 修复后 |
|---|---|---|
| kill 响应抢先于排队的 DATA 和 EXIT | 已连接;保留无头模型和标题跟踪器 | 已断开;两者均释放 |
| 主机清单在排队的 DATA 和 EXIT 之前验证退出 | 尽管有 exited 判定仍为已连接;保留模型 |
已断开;释放模型 |
| kill 响应抢先于 EXIT 且没有排队的 DATA | 已断开;原因仍为 stop_unverified |
已断开;确认为请求的停止 |
| 自然 DATA 然后 EXIT | 已断开;释放模型 | 相同 |
所有八次运行都接收一次物理提供者退出,将所有最终输出传递到渲染器准入边界,发送一次渲染器退出,并调用一次运行时退出监听器。所有情况下新的守护进程清单均为空。额外的回归测试覆盖相同 ID 替换、过期提供者回调、旧版未标记退出,以及使用真实 SQLite 编排数据库的一次性分发结算。
该修复始终在主进程中处理当前 incarnation 的提供者退出。重复抑制仅适用于渲染器通知。当提供者提供 incarnation 时,其标记命名了该已停止的 incarnation,并且无法抑制不同标记的替代项的退出。旧版未标记事件保留其现有匹配行为。匹配的标记会恢复原始停止意图,同时正常的退出原因解析仍处理否定性、未确认的退出。不会丢弃任何输出,也不更改任何线路字段或操作码。
报告关联与限制¶
提前返回的监听器和合成渲染器 kill 退出同时存在于 v1.4.197(#19018)和 v1.4.192(#17344)中。复现出的 connected: true 加上 stop_unverified 状态与 #19018 报告的矛盾相符,并提供了一条与 #19831 相关的具体主进程保留路径。这并不能证明任一用户会话中发生了哪种顺序,解释 #19018 后续失败的清单/关闭协调,或单独证明 #17344 中持久化标签页复活。缺少 diagnostics.memory 行不是进程退出证据;此证明使用所属守护进程的物理退出和新的会话清单。
第二次运行时清理可能再次推进一个已退役表面的拓扑修订。它不会重新发布已移除的表面。现有退出监听器和等待者在结算时自行移除;已完成的分发不再处于活动状态。现有标记超时仍为 30 秒。独立的异步关闭调用在其 await 期间的所有权不属于本次更改。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 orca48/orca