跳转至

服务器更新

一个稳定启动器持有由 systemd 或 launchd 选定的运行时。它是持久服务状态的唯一运行时写入者。服务器子进程通过继承的 IPC 请求更新;它们从不重写自己的服务定义,也不选择自己的替代者。本地服务命令可以在服务停止时替换启动器和状态。前台 CLI 进程不会自我更新。

精确版本安装使重启不依赖 npm 缓存驱逐或移动的发布标签。安装和预检在暂存阶段、发布不可变运行时之前完成。预检检查启动器协议,因为需要新的回滚保证的目标无法在旧启动器下安全运行。升级该启动器需要本地服务更新。

提交边界

启动器在确认更新之前先持久记录待处理更新,然后停止旧子进程并将目标作为试验启动。服务状态写入使用同目录替换,并执行文件和目录 fsync。无效状态会停止启动,而不是猜测要引导哪个运行时。

试验必须完成迁移、获取依赖、绑定 HTTP,并在报告 prepared 之前将所有长期运行的根任务停放在激活门处。然后启动器持久提交目标版本并回复 committed。只有到那时,子进程才能释放其门、接受命令并发布就绪。将可能失败的启动获取操作保持在此边界之前。仅靠监听器并不能证明运行时已准备好提交。

失败或超时的试验会返回旧版本。提交后,目标即成为权威,服务管理器通常的重启策略开始生效。

prepared 截止时间很长,因为迁移可能随数据库扩展并阻塞试验的主线程,因此它无法报告进度。错过截止时间会恢复快照,而重试会再次付出同样的代价。崩溃的试验会在退出时被发现;截止时间仅限制卡住的试验。客户端更新等待必须超过截止时间,否则慢速更新会显示为失败。

数据库回滚

在停止旧子进程之前,启动器会拒绝磁盘上放不下快照的更新,因此磁盘满不会导致中断。旧子进程退出后,启动器对 SQLite 的主文件、WAL 和共享内存文件进行快照。这使得试验迁移无需向下迁移即可保持可逆。快照每次更新只制作一次,并在启动器重启后仍然存在;在重试期间替换它可能会捕获来自失败试验的更改。

回滚在恢复之前停止试验。持久的恢复标记使中断的恢复在任一版本启动之前完成。将快照保留到提交,或保留到恢复和最终回滚状态都已持久化为止。SQLite 之外的附件和其他文件不在该回滚边界内。

客户端确认

已接受的更新仍处于待处理状态。客户端在重新连接后将启动器的更新 ID 与就绪事件关联,然后检查结果和目标版本。仅重新连接无法区分成功替换与回滚。没有更新 ID 的旧服务器仅保留基于版本的关联。

桌面更新有一个单独的两阶段交接,因为安装应用会停止其捆绑的后端。准备阶段在连接仍存活时返回一个令牌;客户端仅在收到该令牌后才提交它。否则后端关闭可能会丢失唯一成功的 RPC 结果。客户端随后必须在重新连接后观察到已准备的版本。如果安装失败,桌面会重启已停止的后端,并为同一令牌重放失败。

恢复中断的线程

重启延续是环境持有的偏好,默认开启。解码失败的 settings.json 会将其关闭,因为该文件可能包含选择退出设置。
v2 恢复服务要求匹配持久的运行、提供者线程、会话和原生恢复身份。

排队的运行从未启动,因此恢复会保持它们,并继续它们所等待的后面的运行。已定局的运行只有在重启取消了代理所等待的工作(子代理、后台任务,或代理标记为 t3_background_wait 的 shell 或监视器)且其会话当时仍存活时才有资格,因此来自较早崩溃的过期记录永远不会唤醒它。其延续提示是一则说明,指出哪些内容不会回报。未标记的 shell 或监视器不会唤醒已定局的运行:它们大多是开发服务器及其看门狗,没有人等待它们,因此该说明会等到下一条用户消息。

恢复会撤销与丢失进程相关的效果,并在持久发件箱中记录延续意图。该意图在提供者启动之前能跨另一次重启而存续。延续效果会等待激活;慢提供者不得延迟服务器的就绪状态或启动器的提交边界。优雅关闭会在关闭提供者之前捕获意图,然后在摄取停止后进行对账,这样迟到的完成不会被过期的取消覆盖。

延续处理程序在分派之前会重新检查偏好、提供者选择、更新的用户工作、用户请求的停止,以及 /compact 之类的维护轮次。意图和投递都会拒绝以下对象:已归档、已定局或仍处于休眠状态的线程;提供者轮次已结束的截断轮次;以及等待用户输入的运行——等待一个待处理的批准、问题或密钥,或等待恢复在该截断轮次上关闭的此类批准、问题或密钥。支持消息的问题仍然可以回答,因此它们不会阻塞。投递还会在同一个 restartContinuationOfRunId 链中连续三次延续后停止,因此导致服务器崩溃的轮次不会循环。稳定的命令和消息 ID 可防止发件箱重试后的重复提交。Codex 恢复时不会添加提供者提示文本,除非该轮次丢失了后台工作;其他适配器通过其正常的轮次路径接收延续消息。

委托任务(delegate_task 子线程)作为独立线程进行对账,而绝不会作为父级的后台工作来处理。编排器会在对账后的启动阶段结算子结果与完成投递,因为终止运行监听器会忽略对账的取消操作。已取消的子项若其重启延续仍在发件箱中待处理,则尚不算是结果;该延续的运行会结算它,或者当处理程序拒绝继续时由处理程序结算它。调度器会等待激活,因此它们无法启动随后会被对账取消的运行。

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