跳转至

排队的渲染器图恢复已退出的窗格所有者

这是针对 #19018 部分问题的独立源码级说明。它复现了执行主机确认退出后,一个排队的渲染器图恢复该 PTY 的运行时 connected 标志,并使实际的 stable-pane 解析器针对后继者的持久绑定抛出 terminal_pane_owner_conflict。

运行

在已安装依赖的检出目录中:

ORCA_BACKGROUND_LAUNCH=1 node docs/audits/queued-terminal-graph-exit/reproduce.mjs /tmp/queued-terminal-graph-exit.json

该脚本使用真实的渲染器图发布者、主 Store.persistPtyBinding、运行时、daemon 服务器、适配器和本地套接字。只有子进程和 IPC 分发边界受控。它会创建临时数据/套接字路径,运行隐藏的 Node 测试,并删除其临时文件。它不会启动 Electron 窗口或安装依赖项。JSON 记录源码哈希,并排除随机分配的终端句柄/实例。

顺序

  1. 正常发布已挂载的前驱者的图。
  2. 在 IPC 分发边界捕获其下一次未变更发布。真实发布者会发送已挂载叶节点、mobileSessionTabs: [] 和 unchangedMobileSessionWorktrees。
  3. 在该发布排队期间,生成后继者并将其持久绑定到同一标签页和叶节点。
  4. 投递前驱者的物理 daemon EXIT。运行时变为 disconnected,并带有 exited 判定。
  5. 投递已捕获的图,不重新排序渲染器发布。
  6. 解析窗格,查询拥有 daemon 的最新清单,并再次发布。第二种变体在该清单之前卸载渲染器终端,之后通过真实注册/发布者 API 重新挂载。

替换绑定提交和 daemon EXIT 可以在渲染器调用排队时运行。生产 spawn 提交在返回其回复之前持久化绑定(ipc/pty/ipc/spawn-commit-persist.ts);图发布者独立读取已挂载窗格的传输。测试夹具控制该顺序;它不能证明其在报告机器上的频率。

退役正确地拒绝删除后继者的持久绑定。在修复之前,保留的表面坐标随后允许旧图叶节点再次将前驱者设置为 connected。健康的清单只包含后继者,但运行时扫描会跳过仍具有图叶节点的记录。列表的展示可以将该叶节点标记为 disconnected,而底层窗格解析器仍看到它是 connected。

结果

变体 首个排队图恢复前驱者 卸载、清单和重新挂载后 窗格冲突
之前 是 是 是
仅退出检查 否 是 首次检查时否
完整修复 否 否 否

所有三个变体还会运行一个没有替换的普通退出对照;它始终保持退役状态。中间变体隔离了为什么在渲染器挂载间隙期间的弱清单缺失必须保留已经获得的退出证书。如果没有该挂载间隙,保留的 disconnected 叶节点会阻止清单扫描忘记该判定。

该修复复用现有的存活判定注册表,使已退出的图叶节点保持 disconnected 且不可写,并跳过重新创建其 PTY/URL-watcher 所有权。它保留表面成员资格:一个独立的实际 stopExactTerminalsForWorktree({ keepHistory: true }) 对照在物理退出已完成但 stop 回复仍待处理时,传递一个已变更的渲染器构建的 mobile 快照。历史表面在渲染器清除其 PTY 绑定之前和之后均保持存在。所有阶段都检查该对照;修复后的阶段还检查 mobile 投影永远不会将一个 PTY 的 ID 与另一个 PTY 的句柄组合。

新的 spawn/注册会清除先前判定;拥有者清单可以建立 live。如果有限 PTY 归档已被修剪,物理退出仍会记录其证书。仅主机测试覆盖相同 ID 替换、过期的前驱者 EXIT、全新的仅渲染器窗格、物理负退出码、本地未验证 stop、SSH 断开连接和保留的历史。可移植证明在其三个源码变体中运行 15 个实际运行时用例。

限制与版本证据

相关的图准入、无条件图 connected 写入、持久退役拒绝和清单叶节点异常均存在于报告的 v1.4.197 中。该标签已经从本地和 daemon 物理退出回调传递 providerExitObserved,并计算 processDeathCertified;本证明的自然退出路径不依赖于 #21000 的合成通知修正。可执行的 before/after 运行使用当前检出和窄断言的源码转换,而不是完整的历史二进制文件。

这证明的是过期的运行时/窗格所有权,而不是已测量的原生进程或堆泄漏。仅凭图不会重新创建无头终端模型。它没有证明每个缺失的诊断行都表示一个已退出进程,也没有解释该问题中所有句柄数量增长。

现有注册表最多保留 256 个无主判定;PTY/句柄/叶节点所有者会保留其判定,直到其自身生命周期结束。disconnected PTY 归档上限为 128。在记录及其有限判定都被逐出后,图没有剩余的按 ID 证书;此更改不会添加永久墓碑。后续的失联写入仍可能将退出判定替换为 unverifiable;过期的正向清单可以单独写入 connected 记录。这些路径未被本本地排队发布证明执行或修复。

另一项独立审计发现,一个不可达且无关的旧版守护进程可能导致聚合精确停止验证失败,即使目标自身的守护进程中不存在该守护进程。该问题被排除在本次修复以及证明的健康目标清单断言之外。

已记录运行的溯源

results.json 记录的是在 #21014 中独立的 provider-inventory 生命周期围栏之前的 graph 修复。其源哈希标识了那次较早的运行;它们并不声称每个后续审计提交都具有相同的字节。该复现可以针对组合工作树重新运行。

拉取请求依赖

graph PR 堆叠在 #21000 之上,复用其守护进程套接字测试夹具和物理退出交付契约。graph 机制是独立的;该堆叠使可执行证明的依赖关系变得明确。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 orca48/orca