跳转至

Electron 取消验证,2026-10-16

#4388、现有 #4387、伞形 #4027。

下文验证了取消边界以及被保留的取消原因。 完整的真实 Linux Joplin 工作流仍为部分通过或失败,因为进程所有权/清理无法被验证。 发布类型化回复、退出 CLI 以及清理其应用程序,是彼此独立的观察项。

源码与确定性回归

最新 main 的对照提交为 fe2a398dd9ab290ba6cb3411403d319cec8d07a2。 已审查的 PR 头部 af732dd8 与上述 main 集成于 3b094802a。 其最初的 47 个聚焦用例全部通过。 一个无关的紧凑目录测试撞上了其未更改的 10 秒 CI 期限;而未更改源码的作业重试通过了。 最初的失败执行仍保留在 CI 历史中。

真实 CLI 验证暴露了一个被引入的回归:该 PR 在最终快照之后,将已观察到的取消替换为成功。 随后的清理失败又丢失了取消类别和调用方原因。 两个确定性用例在进程和传输清理上复现了此问题:20 个旧用例通过,而两个新用例均失败。 main 的公开回复保留了 cancelled 类别;而被审查的 PR 对于同种已取消等待外加不完整清理返回了 execution_failure。

修复 73d4a712b 在最终化之前记录取消,并为早期和晚期部分捕获错误使用同一个构造函数。 清理失败仍保持优先级,并保留其诊断信息和较早的取消原因。 在清理期间首次观察到的取消仍保持现有优先级。 该修复改变了产出结果;未添加 CLI/MCP 投影修复或所有权策略例外。

修复后,三个文件中的所有 49 个聚焦用例均通过。 完整静态检查通过:六个任务加架构守卫。 文档检查也通过(六个任务,包括两个已缓存任务,外加五个 README 一致性用例)。 一次中间构建拒绝了过度收窄的 aborted === true 比较;在通过构建之前,原始的真值判断模式解决了该 TypeScript 错误。 记录的目录元数据与 main 字节完全相同。 未添加新的工具、模式、缓存或常规结果字段。

真实应用观察

未更改的官方 Joplin 3.7.21 ASAR 为 233,575,014 字节,SHA-256 为 767df409b18effe60421fbefcca873de237c7e813eac744ecdeebbc5e825a33a。 获取方式链接见原始 Joplin 验证。 其完整解包的原生文件/资源随附其中。 这些试验使用实际应用程序,搭配通用 Electron 44.7.0、全新配置文件与 Xvfb。 它们演练启动/取消,而非完整的 Joplin 业务工作流。

冻结的验证器修订版 279aa29a7 在最终探测之前记录源码/运行时哈希。 受控用例在真实应用程序运行期间持有 REA 侧的 Playwright 回复。 它们并不能证明存在自然发生的 Joplin 停滞。

受控条件 观察到结果
Main:首窗口回复保持挂起 取消后 20.001 秒仍挂起;验证器看门狗失败
修复版:相同的首窗口回复保持挂起 取消在 5.658 秒内返回;已取消动作被保留
修复版:初始快照回复保持挂起 取消在 5.335 秒内返回;未凭空产生部分快照
修复版:最终快照回复保持挂起 取消在 10.262 秒内返回;五秒取消宽限期到期,且初始快照被保留

每个修复版用例都保留 cancelled 类别。 每个真实用例仍存在未验证的提供方清理和非零验证器退出;这些是取消阶段的证明,而非完整的运行时通过。 已知的 Linux 所有权缺口在 #4282 中跟踪。 并未为了让这些测试通过而从进程名称、PID 或可执行文件路径推断所有权。

公开 CLI 试验在实际 Joplin 启动日志之后发送 SIGTERM。 main 和修复版均发布 cleanup_incomplete,带 cancelled 类别和已取消动作。 修复版回复在 SIGTERM 后约 5.268 秒被观察到(50 ms 轮询精度)。 两者均未能满足验证器的 20 秒首个信号退出期限,并且需要第二个明确记录的恢复信号。 得到的 143 退出码并不能证明第一个信号完成了清理。

官方打包的 Joplin 可执行文件也通过了静态 fuse 准入,但其初始 Inspector 求值在达到取消条件之前因执行上下文被销毁而失败。 这些尝试仍为失败诊断;它们没有确立捆绑运行时兼容性或任何取消结果。

成本、限制与可复现性

耗时操作在单个 CPU 10 上串行运行,具有 8 GiB 硬限制、6 GiB 提前停止、无交换分区和 192 个任务。 通过的静态门禁使用了 153.534 秒墙钟时间、152.274161 family CPU 秒和 6,442,016,768 峰值 cgroup 字节。 它报告没有 OOM,并验证了负载清理。 Cgroup 内存包含文件缓存,而非 RSS。 其他试验的确切计数器和失败情况均保存在精简记录中。

负载退出计数器是在观察者仍存活时收集的,并非最终的完整作用域计数器。 某些失败的探测在该时点仍保留存活的 app/Xvfb 进程。 每个记录的作用域在外部所有者停止后均被独立确认为非活动/已死。 这种恢复并不能证明提供方清理成功。

OS/构建缓存不受控制。超时的基线与部分修复的工作流并不能证明完成任务后的加速效果。实时事件集也有所不同,因此回复大小差异不能证明 token 节省。模型计费、峰值代理上下文以及完整的主机/工具模式 token 成本均未测量。历史诊断辅助工具哈希在执行时未被捕获;记录标记了这一缺口,而不是将后来的冻结哈希分配给早期运行。

构建每个固定检出,然后在现有的资源观察器和私有 Xvfb 实例下运行。共享验证器支持全部四个命名用例:

node experiments/analysis-efficiency/electron-cancellation.mjs \
  --runtime-root /absolute/pinned-checkout \
  --executable /absolute/electron-44.7.0/electron \
  --application /absolute/Joplin/resources/app.asar \
  --profile-root /absolute/temporary-profile-parent --case window-wait

使用 initial-state、final-state 或 normal-wait 作为其他边界情况。公共 CLI 探针没有注入停滞回复:

python3 experiments/analysis-efficiency/joplin-cli-cancellation.py \
  --node /absolute/node-24.18.0/bin/node --runtime-root /absolute/pinned-checkout \
  --executable /absolute/electron-44.7.0/electron \
  --application /absolute/Joplin/resources/app.asar \
  --profile-root /absolute/temporary-profile-parent

当真实自有的应用仍未确认退出时,脚本返回失败,而不是声称已完全清理。应用二进制、提取的运行时/配置文件以及原始大输出均可重新生成,且不会被提交。未声称在 macOS、Windows、完整 Joplin GUI 或实时模型上取得成功。

审查后续:验证器退出语义

对 beb4a47db 的审查发现了一个验证器误通过:共享探针可能在其主进程退出后即成功退出,即使 provider 清理仍未验证。CLI 探针也接受了 cleanup_incomplete。这些是验证器缺陷;它们不会使上面记录失败的 Joplin 试验失效。

修订版 227217ac3 要求两个探针都进行已验证的 provider 清理,并在 CLI 中要求公共 cancelled 类别。六个受控 oracle 用例涵盖了:已退出主进程但清理不完整、清理完成、进程清理后传输失败,以及错误的公共类别。两个旧脚本均未通过这些回归测试;修复后的脚本全部通过六项。这些用例替代了 provider/CLI 回复,并不证明真实 provider 兼容性或性能。

修复后的冻结脚本随后在同一个真实 Joplin 工件上重新运行。共享的 window-wait 探针在 5.577 秒时仍保持取消状态,并因清理仍未验证而明确失败。公共 CLI 保留类别 cancelled 和已取消的操作,在 SIGTERM 后约 6.335 秒发布其回复,并再次未通过首个信号退出截止时间。两个验证器均以非零状态退出;它们外部持有的作用域被单独停止。生产源代码和之前的历史记录未更改。简明记录在 review_followup 下追加这些观察结果。

请将受控 oracle 回归测试与真实应用命令分开运行:

python3 experiments/analysis-efficiency/electron-cancellation-oracles.py \
  --node /absolute/node-24.18.0/bin/node

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