Skip to content

1.0.2 build 37: the updater no longer kills itself - #219

Merged
wangzhizhou merged 1 commit into
mainfrom
dev
Nov 5, 2026
Merged

wangzhizhou merged 1 commit into
mainfrom
dev

Conversation

@wangzhizhou

Copy link
Copy Markdown
Contributor

真机演练 1.0.0 → 1.0.1 时发现:宿主升到了 36,但更新程序仍是 34、updates/receipts/ 不存在、staging 残留。同一套参数在临时目录跑 UpdateInstaller.install 完全成功,差异只在「更新程序正在替换它自己」。

根因(报告 226)

replaceBundle 替换前统一调 environment.stopHost(...);自更新传的是 DefaultInstallEnvironment.make(target: .updater),它的 stopHost 会 lsof 该可执行文件并 SIGTERM 持有者——持有者就是正在跑这次安装的更新程序。进程当场被杀,事务停在「宿主已换、回执未写」,defer 不清理 staging。

这与 ADR-295 写下的「运行中的实例保持不动,下次启动生效」相反。

修法(ADR-306)

新增 DefaultInstallEnvironment.stopsRunningInstance(_:) 作为唯一判定点:.updater → false(不停),.production → true。运行中的 bundle 允许被 rename 替换,下次启动用新版。

验证

  • install-core.swift 新增两条断言:生产停宿主、自更新绝不停更新程序
  • make verify PASS;离线 56 文件 / 303 例 PASS
  • 构建号 36 → 37,版本 1.0.1 → 1.0.2

归因补充

以前没发现是因为:单测用假环境(stopHost 空实现)、隔离演练里 applications == nil 根本不做自更新——真实路径从未被走过,这也解释了该验收项为何长期 BLOCKED。

发布后我会用「更新程序版本 ≥ 宿主」的一次安装做端到端复验(回执写入、staging 清理、更新程序被替换、进程不再自杀),结果追加进报告 226。

Replacing the updater bundle ran stopHost first, whose lsof-and-SIGTERM
lookup found the very process performing the install, so the transaction
died after swapping the host and before writing the receipt, leaving
staging behind and the updater untouched.

stopsRunningInstance now decides once: production stops the host, the
updater target does not, because a running bundle can be renamed and the
next launch picks up the new one. Version 1.0.2, build 37.

Signed-off-by: wangzhizhou <824219521@qq.com>
@wangzhizhou
wangzhizhou merged commit 08af103 into main Nov 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant