原生 Electron once 分发 — 2026-10-16¶
4593 是由对 #4562 的评审上报的,但其来源已随 #4389 合入 main。初始报告明确仅涉及源码;随后的配对控件确认了该缺陷。此变更将 once 的创建、触发和可调用选择委托给实际运行时,并且只观察已确立的回调入口。CLI 和 MCP 继续共享相同的 hook、事件模型、投影和保留的 Evidence。没有引入新的工具、schema、执行权限或分析缓存。¶
配对的原生对照¶
基线为 709b5cbdc15aa757f89c38ecd12e5a47710747a6。最终源码为 4ebd0f60e860daa57a7033c6e77ea7f5f4b8ac97,包含下面两个评审缺口修复。更早的源码队列 c0b52b5408fa97013798e6ecee885ccac08e7356 包含该修复;最终清理提交为 e60c4a1098321ed2a7f564ae35909a31d707694f,它在检查了每个调用者后,移除了过时的第五个辅助参数以及不可达的复制 call/apply 分发分支。评审前缺口负责人的后续提交为 7f05f476c52498adba41d943ead1a86e7216ca76。相邻 JSON 保留了源码哈希和独立的测量队列,包括最初的 93 行前缀。最终评审 JSONL 包含 117 个配对行(39 个输入 × 3 个运行时)。较早的 96 行 JSONL 保持不变,包括其最初的 93 行前缀。两次比较的每个前后配对中都有相同的原生控制事实。可重新生成的二进制文件、应用、剖析数据和多 MB 原始捕获均从 Git 中排除。
| 实际引擎 | 用例数 | 基线行为差异 | 修复后差异 |
|---|---|---|---|
| Node 24.18.0(固定版本) | 39 | 4 | 0 |
| 官方 Node 24.21.0 | 39 | 16 | 0 |
| 通用 Electron 44.7.0 内嵌 Node 24.21.0,作为 Node 运行 | 39 | 16 | 0 |
最初的 21 用例复现分别发现了 0/9/9 个差异。评审前的 32 用例队列发现了 1/13/13。最终的 39 用例套件新增了只读回调方法、emitter 方法不变量、原生元数据写入、失败恢复和不可调用回调方法。额外出现的固定运行时差异是注册元数据排序。在较新的运行时上,不透明回调方法可以在旧 hook 下抑制回调,尽管原生分发会执行它们。当不透明方法合法跳过回调时,固定运行时也会捕获到虚假的调用记录。针对该虚假事实新增的回归测试在基线上失败。
这些是使用最小 Electron 模块的受控生产者用例,包含实际的嵌入式 Node 二进制,而不是真实 GUI 应用中自然发生的回调丢失。原生追踪、接收方检查、失败和剩余监听器都会被精确比较。预期的属性读取是从每个运行时推导而来,而不是从某一个 Node 实现复制而来。当运行时实际调用该方法时,custom-apply 守卫仍然检查其原始 Arguments 表示。
所有权与不确定性¶
原生 once 包装器保留其公开回调身份和描述符属性。注册接收器将方法/getter 转发给原始 emitter,并支持只读方法描述符。私有可调用对象会接收真实的 Arguments 帧,从而在记录时避免应用的 Array species/迭代器。元数据识别与准入共享一次有界的描述符查找。
应用选择的不透明 call/apply 可能绕过观察;一个有界的 custom-call/custom-apply 缺口取代了虚构的调用事实。不透明的原生元数据写入或注册查找保留确切的原始回调/原生操作,并发出 once-metadata 缺口。即使注册抛出异常,临时未观察作用域也会被恢复。39 用例套件检查了该恢复,包括一个绕过已修补 on 的原生别名;once 所有者保留该路径的观察缺口。#4513 中原始 recording-wrapper 的变更仍然明确不予修复。
评审发现了两个缺失的失败事实:装饰器可以通过未挂钩的别名进行注册并随后抛出异常;运行时可以在分发失败之前读取不可调用的 call/apply 属性。这两个新增回归在评审前源码上均会失败。once 所有者现在在恢复作用域之后,于 finally 中最终确定其缺失的缺口;可调用元数据所有者在记录失败缺口的同时保留确切的不可调用值。错误身份和原生回调行为均得以保留。
两个短生命周期代理用于可观察的 once 注册。元数据保持弱保留,现有的事件/序列化预算继续生效。新增的注册成本未被单独衡量;不声称任何速度或 token 改进。保存的生产者比较是一个正确性实验,而不是整个应用程序的性能基准。其运行器会报告差异,而不会因预期的不良基线以失败状态退出;回归测试断言修复后的行为与原生行为一致,并且观察声明是真实的。
真实应用验证¶
未修改的 Joplin Desktop 3.7.21 ASAR 和显式指定的通用 Electron 44.7.0 运行以下工作流:随附的欢迎笔记/1075×666 PNG → 实际资源上下文菜单 → 应用桥 → 被阻止的 reveal 工作流。图像保持可见,页面错误保持为空,reveal 事件从 0→1,共享的保留捕获中包含确切的事件。两个暂存的 hook 文件在启动前会与所选源码进行哈希比对。没有添加任何合成的应用 IPC 通道或替代应用回调。
argv shim 是一个显式测试适配器,用于仍然失败的标准启动 #2974。整体 provider 清理仍然失败(#4282),验证器以非零状态退出。外部作用域拆除不是 provider 清理。第一个冻结的真实流水线耗时 17.680 秒;观察到的 payload 退出 CPU 为 16.272793 秒,峰值 1,395,253,248 B,且存在一个额外的后代,因此完整进程族观察未经验证。清理队列单独记录。评审前的 32 用例源码成功重复了真实操作,但整体清理仍然失败:流水线 18.074 秒,观察到的 CPU 17.011774 秒 / 峰值 1,422,839,808 B;完整进程族测量仍未经验证。不声称有已完成的公开 CLI/MCP 工作流、真实 Windows/macOS 运行、自然应用回调丢失复现或完整 check:pr。
最终审查源码重复了相同的实际操作:18.353 s 流水线,观测到 CPU 17.098599 s / 峰值 1,387,556,864 B;完整族测量仍未得到验证,整体 provider 清理失败。较早的一次试验未能初始化显示,因为 provider 环境缺少 XAUTHORITY。那次启动被单独保留;新的最终试验使用本地 Xvfb(带 -nolisten tcp -ac),而不是生产 provider 变更。
固定的本地验证:两个 Node 版本上均有 75 个 hook 用例;在未更改的共享契约上有 5 个 projection + 8 个 MCP 用例;静态检查通过(最终 118.946 s 墙钟时间 / 117.752622 s CPU / 4,282,826,752 B cgroup 峰值,已验证 payload-exit 族观测)。固定的最终运行使用 test:focused;一次尝试的 test:local 调用在测试运行前被拒绝,并记录为未执行。确切的命令/队列、失败的候选尝试、源码固定和测量资源请参见 JSON。失败包括 Array-species frame、readonly receiver 不变量、metadata setter 同一性、on-getter 排序、一项 lint/互操作性修正以及 helper 准备失败。它们不会被重新标记为最终源码的结果。
所有重型工作均串行运行,使用 CPU 10/quota 1、8 GiB 硬限制/6 GiB 早期限制/无 swap/192 个任务。计数器在 payload 退出时、observer 仍存活的情况下捕获,而不是最终全作用域计数器;cgroup 峰值包含文件缓存。每次最终 Joplin 运行都有一个新的私有配置挂载。文件系统/运行时/构建缓存均为热缓存;冷系统和热重复运行成本未测量。Agent/计费 token 以及公开回复/上下文成本未测量。宽泛的内部错误捕获大小不是 agent-token 度量。所有拥有的作用域均被独立检查为 inactive/dead。
复现生产者比较¶
使用固定的项目工具链,以及显式提供的备用运行时。备用 Node 24.21 归档已根据官方校验和进行核对;其归档/二进制哈希已被记录。没有升级任何全局工具链。
python3 experiments/analysis-efficiency/electron-once-runtimes.py \
--hook-root /absolute/checkout-to-measure \
--node /absolute/pinned-node \
--node /absolute/node24.21 \
--electron /absolute/generic-electron44.7 \
--output /absolute/owned-output
在已记录的资源 wrapper 下运行该命令。对于基线对比,使用 709b5cbd 的全新检出作为 hook-root,同时保持相同的当前 oracle/runner。runner 会保留完整 JSON 并打印简洁摘要。真正的 Joplin 配方位于 shell 验证器记录 中;选择当前的 runtime-root。该工作流在 cleanup 失败时必须保持非零退出状态。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 rea2/rea