中继区域修正 — 空闲切换计划¶
Status: 修订版 2 — 设计已批准;实现与验证待完成。
独立的 GPT-6-astra 低风险审查未发现剩余的设计阻塞。批准以下列实现门禁为条件:await 前所有权核算、共享 assignment 行序列化、加锁的歧义结果对账、操作身份去重和迟到回调隔离,均须在测试中得到验证。已保守地计入了四次独立的空闲范围审查(范围、plan v1、简化、修订版 2)。如果又一个计划修订版未通过审查,并且需要第六轮,请停止并等待用户重新评估。批准并不意味着当前的 live-retention PR 已实现此设计或已准备好合并。
要求与刻意权衡¶
当没有中继客户端正在使用主机的中继区域时,自动改进该区域。手机和 iPad 同时断开连接可以创造机会。持续在线的客户端可能会无限期推迟优化。移动期间返回可能会产生普通的重新连接延迟;零延迟重连不是要求。不要为了优化延迟而故意关闭已建立的客户端连接。直接 LAN 会话和正在运行的终端进程本身不计为中继客户端。
移动端 30 秒后台宽限期不是可靠的可调度事件:操作系统可能延迟它。请使用实际的源 cell 连接状态。桌面控制端在没有手机时仍保持打开;不要等待它自然消失。
保留新鲜的桌面测量、相对现有区域的 25ms 且 20% 改善、分组/启用控制、容量检查和冷却时间。探测改善并不能证明应用延迟已改善。云选择权威 assignment;移动端重连读取 assignment,而不是自行选择更快的区域。
简洁性约束¶
复用区域 worker、assignment 事务、预留(reservation)、请求身份、cell 准入注册表和正常的桌面重连。不要引入 live-source 保留、splice 转移、周期性保留控制租约、新的移动端协议、全局空闲轮询器,或桌面后台断开定时器。现有数据套接字永远不会被复制或转移(之前的设计也没有转移它们)。
尝试一次空闲机会;如果忙,立即推迟;不要让门禁一直等待用户离开。门禁只存在于一次短暂的尝试切换期间。可重试的到达可能在这场竞态中落败并正常重连。不要将此视为执行丢失的证据,也不要重放之前已发送的 mutation。
源 cell 已经共享 assignment 数据库。在一个受约束的 assignment 事务周围使用一个由源端拥有的本地屏障;不要引入分布式 prepare/commit 协议、持久化准备表或第二个准入服务。director 选择候选;源端的事务会重新检查 director 的策略。
什么是空闲?¶
源端拥有一个按主机/代(generation)划分的准入屏障,覆盖所有 accept、attach 和控制替换路径。在修改这些路径之前,先清点它们。静止(quiescence)谓词必须要求:
activeConnIds.size === 0(包括持久化等待期间的 attach)。activeSplices.size === 0且pendingConns.size === 0。- 在插入到这些 map 中之前,在途 accept 数量必须为零。要在第一个可能接纳此主机的异步操作之前跟踪所有权;每次退出都释放它。
- 在途控制操作必须为零:这些操作会安装凭据、改变连接基础或创建准入。跟踪实际服务器处理器;不要根据 RPC 流量或旧数据库租约编造一个近似计数。
一个已认证的打开状态桌面控制套接字、其 ping/pong 和活动续期不是客户端工作,也不是推迟的理由。它们可以一直保留到切换关闭这个空会话。屏障之后到达的桌面请求会收到普通的可重试传输错误;在宣称空闲之前,先完成先前已接受的状态 mutation。重连必须保留配对关系,且不能盲目重放 mutations。
缺失或过期的数据库活动租约永远不能证明空闲。未完成的预留清理仍由源端负责,必须完成或安全隔离;但等待所有租约过期会错误地等待健康的控制租约。
源端主导的尝试切换¶
-
director 使用现有资格和节奏以只读方式选择候选。它发送一个已认证的空闲切换请求,包含稳定的操作 ID、预期的源 assignment epoch/incarnation/generation 和候选目标。选择不会预留容量或更改 assignment。重复投递使用相同的 ID。
-
源端验证请求和当前会话。在一个同步段内,检查所有计数器并安装按主机的屏障。如果忙,返回
busy,不关闭套接字,也不持有屏障。忙是推迟,不是分发失败。下一轮 worker 遍历必须越过忙的候选,而不是让其他候选饥饿。 -
屏障生效期间,拒绝新客户端以及任何新的源控制激活/重新绑定。迟到的异步续体必须在每次 await 之后重新检查屏障/会话,并释放被放弃的预留。在切换的第一个 await 之前安装此围栏。任何屏障定时器都不得自行重新打开准入。
-
源端调用现有 assignment 事务的受限版本。复用其锁顺序、全局速率/并发控制、冷却时间、容量预留、新鲜度和安全检查。重新检查精确的源 epoch/incarnation/generation、目标和操作身份。原子地预留目标、更新 assignment/epoch 并记录现有的持久化迁移/尝试。不要调用当前不加限制的
claimRegionalRehome,让它选择另一个主机。数据库锁内不得进行网络调用。零套接字是在本地确定的,而不是从活动租约推断出来的。 -
如果提交成功,通过现有的 resolve-director 关闭路径淘汰仍然为空的源会话/控制,并释放其活动。桌面端使用正常重连并在目标上注册。使用持久化的操作结果进行回复。
-
如果明确未提交且源端权威(authority)保持不变,则移除屏障并在原始控制上继续。回滚的事务不会保留任何目标预留。如果权威已改变,则改为淘汰过时的源端。超时或传输错误不是明确的回滚。
模糊事务、重启与故障¶
请求操作 ID 在事务之前已知,并在提交时记录为现有的尝试 ID。重复调用返回其结果,且永远不会启动另一次迁移。并发的重试、取消或确定性中止检查必须在与提交相同的 host lock 下串行化;未加锁的缺失行查找是不够的,因为原始事务之后仍可能提交。
保持屏障,直到数据库事务已知终止,并且加锁的对账确立了结果。如果驱动结果不明确,通过每次尝试的回退回调重试状态,使用相同的身份。如果持久访问不可用,保持隔离;在分配的权限未知时,不能承诺有界可用性。不要仅因超时重新打开。使用现有的 DB 事务超时和请求超时,而不是新的可续期门控租约。
丢失的 director HTTP 响应不会中断源端拥有的完成:源端完成其事务,读取持久结果,并在本地关闭/重新打开。来自任何 director 的重试都会看到同一操作。director 崩溃不会搁置准备,因为不存在独立的准备。
源端重启/替换控制由现有的权威注册和活动验证进行隔离。它必须在 host lock 下与切换事务串行化,验证当前分配,并在提交获胜时拒绝旧的源端所有权。如果替换获胜,旧事务必须在其 generation/incarnation 重新检查中失败。这需要追踪当前注册持久化并证明共享串行化点,而不是仅依赖内存中的隔离。来自已关闭会话的迟到回调不能为其替换重新打开准入。紧急排空使本地权限失效并参与此串行化;已提交的切换遵循其结果,绝不重新打开紧急源端。
提交后,目标端注册失败使用普通的有界迁移恢复。即使结果投递失败,也必须释放旧的空白控制;否则,在源端活动仍然存在时,当前回滚会拒绝(assignment-store.ts:6923)。源端进程死亡由正常的活动过期和 cell incarnation 隔离处理。没有丢弃任何活动客户端,但返回的客户端可能需要等待恢复。一旦客户端在目标端附加,按照普通分配规则保留它们:初始源端空闲永远不允许关闭未来的目标端客户端。
兼容性与权限¶
移动端已经通过 dialRelayThroughDirectorFallback 在 WRONG_CELL(4409)上重新解析;对于到达受门控源端的连接,使用该现有关闭代码。提交之前,解析仍可能返回旧地址:现有回退必须防止紧密重试循环。提交之后,它返回目标端。固定旧解析器/客户端测试夹具,并测试实际代码;不要假设每个错误都可重试。不要引入新的移动端关闭代码或协议消息。
空白 host 控制关闭使用现有的 DRAINING / resolve-director 路径;对照基线桌面实现验证其重连行为。为参与 cell 和已更新桌面协商一个不同的空闲切换能力;不要复用 finish-existing 能力来暗示此新行为。不支持的参与者跳过可选纠正。保留旧服务器 HTTP-400 回退用于测量字段。紧急排空/认证执行可以使任何进行中的切换失效;它必须隔离迟到提交并保留现有硬截止期限。禁用纠正会停止新尝试;现有尝试仍会对账。
评审与实现门控¶
评审必须在批准实现之前验证共享存储串行化,并识别每个准入和控制变更路径。最低测试(对新保证先红后绿):
- 手机保持连接而 iPad 断开:不移动。两者都断开:可能移动。 安静的已建立 socket 或过期的 DB splice lease 仍会阻止移动。
- 接受屏障前/后,接受等待活动持久化,附加等待基础持久化,以及跨越屏障的凭据变更。没有迟到附加、泄漏预留或中断的已建立客户端。
- 繁忙尝试保持源端准入可用;重复的繁忙 host 不会饿死空闲候选者或消耗 dispatch-failure 预算。
- 提交/替换竞争;丢失数据库/HTTP 响应;事务期间超时;重复 worker;director 崩溃;源端重启;替换控制;过期 epoch/incarnation;数据库中断和恢复。不要仅因超时重新打开。
- 注册前和新客户端附加后的目标端失败;源端控制释放;普通恢复完成而不进行保留源端恢复。
- 提交前和提交后的当前/旧移动端重连,同地址重试节奏,配对保留和无变更重放。旧/新桌面/云组合。
- 切换期间的紧急排空/认证拒绝;不改变硬排空行为。
- 两个客户端的真实 TCP WebSockets,准入竞争和失败切换,独立执行进程身份和 append-once 变更证据。Docker SSH 和文件夹工作区连续性。测试使用
ORCA_BACKGROUND_LAUNCH=1。
保持测试相称:先确定性组件竞争,然后真实传输、相关云/桌面套件、types/lint 和 PR CI。仅在 55440 上验证权威事务时使用 PostgreSQL。不要用更弱的断言替换失败的 oracle,也不要累积镜像实现的测试。
在干净评审后,替换两个草稿 PR 上被取代的功能代码/测试/文档,保留不可变备份。新鲜度和适当的兼容性测试保留;仅保留机制和发布要求如果不相关必须移除。不要从被取代设计的测试中声称就绪。
发布与合并就绪分开:打包混合版本、物理设备后台计时、Linux/Windows、有界滚动和可测量用户收益仍然是明确的证据要求。本计划不授权部署或启用。
实现说明 — 2026-09-11¶
经过身份验证的 director 命令会携带其已配置的群组百分比和新的进程安全快照。单元不能使用自身默认值为零的 director 群组设置来授权或拒绝选定主机;它会验证经过身份验证的命令,合并 director/源安全,并在现有事务内重新检查持久策略、主机的群组桶以及机群/目标安全。这些字段位于内部管理端点上,而不是移动端或桌面端协议中。
候选选择是只读的,并使用轮换的页偏移量来越过繁忙主机。由精确的源权限和目标派生的确定性 UUIDv5 会在 director 重试/重启期间保持操作身份稳定。这两项细节仍需要最终实现审计和明确的页边界公平性测试。
当前聚焦和真实传输结果记录在验收文档顶部。它们并未完成剩余的兼容性、清理和 PR 门禁。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 orca48/orca