跳转至

Relay 自动区域校正 — 实施计划 v2

状态:已实现并通过本地验证;发布门禁仍然存在。第 5a 节对首次授权采用、保留源回滚、续期和清理具有规范性。本文档取代仅限空闲连接的提案。历史设计评审保留在合并备份修订版中;当前验证和剩余差距记录在验收文档中。

实施跟踪:实时检查清单。已完成的工作和验证证据记录在其中;本文档定义行为。

结果与精确术语

更新后的桌面端获得可靠的区域偏好。如果其分配的区域明显更差,现有的 director worker 会将更好的区域作为新连接的目的地。现有的物理中继数据连接继续通过旧 cell,直到它们自然关闭或失败。桌面端随后释放旧 origin,持久迁移完成。

“现有连接”指物理的客户端到桌面端中继数据连接,由 cell splice 和桌面端连接所有权表示。它可以承载多个命令和订阅;它不是终端进程、agent 运行、已保存的配对或最近的打字记录。受跟踪的挂起附件和绑定 basis 的控制请求也保护源退役。静默的活跃连接将被保留。尚未为可选优化建立或提议固定的最大连接时长。

对于移动端:活跃使用仍留在旧 cell 上;在应用实际挂起/关闭该连接后,下一次成功连接将解析到目标。当前移动端在 30 秒后调度后台挂起,并在回到前台时检查是否已过截止期限(如果计时器未运行)。应用保持前台时放下手机不算断开连接。仅因位置迁移不需要重新配对。

承诺:可选区域优化不会仅因其宽限计时器到期而故意终止预先存在的连接。这不是针对网络故障、进程退出、吊销/过期认证或紧急维护的保证。目标启动期间的新连接尝试可能需要正常恢复;不要承诺这些尝试零延迟。

证据与复用

源实验使用了 721a2692893ab29f8daee3149965bf5e9adf99a0 处的 origin/main。评审必须获取当前 main 并记录其 SHA,以区分已更改的源码与这些带日期的结果。

  • 双向 worker 已存在于 #19241 中,且早于已部署的 #19915。不要实现第二个放置/迁移引擎。
  • 桌面端 relay-origin-pool.ts 已经会打开目标、保留源连接所有权,并在最终释放后关闭源。认证刷新已经会访问每个 origin。
  • Cell host-session-registry.ts 具有仅排空状态、活跃/挂起连接映射和现有的控制续期。Director 存储已经保留迁移状态,直到源活动释放。
  • 两个无条件截止期限位置强制中断:桌面端 origin-pool 和 cell 区域主机排空。在诊断快照中移除这些调度位置使两个保留测试通过;恢复源码后,相同的测试再次失败。
  • 一个 SQLite 存储测试在模拟的一小时内维持了已注册的迁移,两个控制均续期,然后在源释放后完成。
  • 移动端测试装置在模拟排空后恢复了凭据/分配/订阅。已发送的变更可能变为投递未知,且不会被盲目重放。251ms 假时钟恢复结果不是实测的真实世界停机时间。

完整证据:中断发现、测试装置和补丁。反事实补丁并非生产代码:它没有协商机制,错误地改变了正常截止期限语义,并且未验证失败/重放路径。

1. 有序、会过期的区域决策

复用桌面端采样和现有的分配交换。将遗留放置提示与移动现有分配的资格区分开。

保留冷启动放置:运行现有的放置前探测,并在第一个分配请求中发送其放置提示。不要仅仅为了获得测量窗口而创建默认区域分配。在第一个分配时或之后获取绑定 epoch 的窗口;只有后续的窗口后测量才能认证迁移资格。测试使用结论性探测和不使用结论性探测的首次放置,以及旧服务器回退,以便新的迁移协议不会使初始放置退化。

提议的具体协议:一个选择加入的、由服务器颁发的测量窗口。支持该协议的桌面端请求窗口;director 返回按主机的单调 generation、固定的服务器过期时间,以及现任分配的 epoch/区域。颁发后继者会使前任对迁移失效。桌面端在收到窗口后进行探测,然后报告该 generation 的结论性或非结论性决策。重复投递不能延长过期时间。非结论性结果作为 tombstone 保留;延迟的旧结论性报告不能恢复资格。无法复用有效缓存决策的重启将获得后继窗口。服务器时间对过期时间是权威的。

在现有偏好状态中持久化窗口 generation/过期时间、现任 basis、受支持的探测策略版本和结果。仅保留最新的受支持证据;不保留每次探测的历史。重复的同一 generation 决策是幂等的;冲突的同一 generation 结果不得将非结论性升级为结论性。按 broker 串行化窗口颁发/报告,并在 claim 锁下拒绝过期的分配 basis。确切的 schema 和事务顺序必须在实施前进行评审。

遗留的仅枚举请求保留放置/重连行为,但不能继承或覆盖已验证的迁移资格。显式的新的非结论性决策与缺失的遗留字段是不同的操作。诊断性区域覆盖不是经过测量的证明。新的请求和响应字段需要显式选择加入,因为两个 schema 都是严格的。在客户端之前部署服务器支持;为请求结构和响应协商实现旧服务器 400 回退,而不改变健康的分配。

2. 与实际分配区域比较

保留当前预热、样本数、离散度拒绝,以及两个区域均可测量的要求。初始放置可选择最佳测量区域。移动现有分配还要求目标延迟至少比已测量的现有区域低 25ms 且低 20%。这些是应用于正确基准的现有迟滞阈值,而不是经过生产验证的最优值。

报告紧凑的比较证据(现有/目标区域计时、策略和原因),并关联到窗口和分配 epoch。Director 验证边界、资格和裕量。缺少现有区域、目录不完整、测量被拒绝、区域几乎持平、策略不受支持或分配依据过期,均意味着不移动。升级时清除旧版探测缓存,且不得将无对手或 1ms 获胜者视为迁移证据。

这优化了 desktop 到 region 的路径。在声称端到端用户收益之前,在 rollout 期间采样实际 assigned-cell 和移动应用行为。

3. 刷新所有权和节奏

broker 拥有一个决策截止时间和一个进行中的刷新/报告任务。broker 关闭时取消它们。复用成功的 24 小时缓存间隔和 1 小时不确定重试间隔,并带抖动/退避;资格过期与重试调度不同。不要为探测唤醒离线/休眠 desktop。恢复时,在使用过期资格前检查截止时间。仅在现有生命周期提供可靠信号的地方,对网络变更刷新进行防抖。

探测/报告失败不得导致成功的 auth 续期失败,也不得有意重连健康的 controls。使用 drain/recovery 串行化分配响应应用:相同 cell/epoch 更新元数据;较新的分配遵循现有 target 激活流程;过期响应被丢弃。报告重试复用同一决策/窗口,而不是重新探测或延长过期。在开放迁移期间,不要认领另一个移动或替换保留的 source;刷新决策仅可存储以供后续重新评估。

4. 扩展优雅迁移以完成现有连接

为可选区域优化引入显式 opt-in drain 模式。将其持久化在 attempt 上,并通过 director 到 cell 的 host-drain 命令以及 cell 到 desktop 的 drain 消息传播。source 必须从持久协议状态学习模式,而不是从 grace=0、hostname 或重试次数推断。维护/紧急 drain 保持当前硬截止时间。

资格需要支持的 desktop 和 cell 能力、新鲜决策以及匹配的 source epoch/incarnation。新协议/能力值和 strict-parser 回退需要跨版本测试。不受支持的参与者推迟可选纠正,而不是回退到强制关闭。评审者应质疑 host 能力如何保持绑定到当前活动的 source generation,而不仅仅是一份过期的携带版本的报告。

标称转换:

  1. 现有 claim 预留 target 容量,并提交 target 分配以及 migration/attempt 状态。
  2. source 接收携带模式的 drain,并在确认/切换前建立 section 5a 中指定的第一个有效授权 grant;desktop 通过现有代码解析/注册 target。
  3. target 成为 desktop 的活动 origin。现有 source 连接保留其 source 所有权;新连接解析当前分配。已准入的待处理 source 连接可以完成 attach 并留在那里。
  4. 可选区域模式不安装强制旧 origin/session 关闭截止时间。现有事件回调在其最后一个拥有的连接和待处理控制操作结束后退役 source。保留正常 auth 执行和运维紧急关闭行为。
  5. source 控制释放/孤儿清理移除其剩余活动。现有完成逻辑在 source 活动消失且 target 存活后最终化迁移。

不要使用 DB splice lease 缺失来推断空闲:这些 lease 可能在活动 socket 上过期。该设计相反允许 source 工作存在。不要构建所提议的移动前全局原子空闲门。

必需的集成检查:当待处理 control-RPC 完成是最终未完成项时,必须触发退役;attach 超时/拒绝和迟到的异步准入不得泄漏 origin 或在退役后 attach。保留现有 source/target 身份和请求所有权。覆盖两个同时移动客户端和一个安静连接;终端计数和工作区类型不决定传输生命周期。

5. 故障、重放和有界资源使用

本节是必需的实施工约,而不是当前实现已经满足它的证据。

条件 必需行为
target 注册失败 保留仍然存活的 source 工作;使用现有迁移恢复进行重试或对账。仅通过 section 5a 的保留代回滚恢复 source 新准入权限;不要丢弃仍拥有连接的迁移。
丢失回执 / 重复 drain / 零 grace 重新 drain 读取持久模式并保留现有工作。重放绝不能将可选模式变为强制关闭。
desktop 重启 / source generation 替换 旧进程连接可能已经消失;在保留或清除状态之前对账精确 generation。不受支持的替换不得静默 hard-drain 现有工作。
source 网络/cell 故障 使用现有故障恢复;连接丢失不是远程执行已退出的证明。这不在“不故意中断”承诺范围内。
target 在活动后失败 保持仍然存活的 source 连接;通过现有恢复对账分配/新连接,而不启动第三个重叠 rehome。
auth 过期/吊销或紧急 cell drain 保留现有执行;优化不豁免 session 的安全/维护生命周期。
条件 所需行为
最后一个源数据连接在 control RPC 挂起期间关闭 等待有界 RPC 完成/超时,然后运行清理,不使用轮询循环。
源保持忙碌数小时 在健康时保持迁移打开。仅长时间本身不会强制关闭用户或消耗 dispatch-failure 预算。

除每分钟启动数外,还需限制 并发打开的迁移。计入已存在的尝试;每个主机仍强制一个迁移。保留两个 control 的 auth/lease 续期,并计入源使用量加目标预留。数据不会重复;额外的 control/预留仍会消耗容量。

确保现有 100 行 lease-refresh 和 10 行 candidate/sweep 页面中的公平进展;等待中的旧迁移不得使新迁移的注册、续期或清理饥饿。在验证公平遍历之前,先执行一个低于最小相关页面容量的保守并发上限,并计入现有打开的工作。cohort/policy/capability 过滤器应位于 LIMIT 之前,并在锁下重新检查。

不声称存在用户可见的最大 drain 时长。如果运维后续因优化需要该时长,强制关闭会改变产品承诺,并需要明确决策;更大的定时器并不等同于 finish-existing 行为。

5a. 审查更正:保留源权限与生命周期

独立审查发现了三项必需契约。本节取代上述任何认为不变的 auth 续期或通用回滚就足够的建议。当前 source-control 生命周期为六小时,并带有三十分钟抖动;auth-refresh 不会延长它,普通轮换只续期活动目标。当前 durable rehome 刷新也有 24 小时年龄上限。一小时 SQLite 实验证明,这两条路径对于无限期实时保留都不安全。

复用 cell 的现有活动续期(取代额外的 wire 交换)

后续调查发现了更小的机制:一个成功验证的 renewControlActivity 结果可以将同一保留 control 的内存 lease 延长到 max(existingExpiry, requestedActivityExpiry)。cell 已经运行该续期;无需新的 desktop 续期定时器、旧源重绑定或周期性 WebSocket 交换。参见 原型证据。

在确认可选 drain 并告知 desktop 切换之前,必须为确切的 mode/attempt/source generation/incarnation 建立首个短期授权续期。后续授权复用正常 heartbeat 续期。采用期间的失败或过期状态不授权保留源;通过下文回滚契约协调临时目标。仅 mode 标志、待处理数据库请求或 activity 重新获取本身不构成授权。

使用保留的 attempt/mode/source 基础,缩小现有原子数据库续期谓词,使用不可变字段并保持现有锁顺序;避免可能竞态变更的新预检查/查询。成功回调仍必须匹配捕获的 attempt、活动 session/socket/generation 和 mode;retirement/rollback/replacement/emergency drain 会使它失效。使用请求开始时发送的 deadline(当前提前 105s),而不是响应时间,并且不要在每个 heartbeat 上增加六小时。保持正常 JWT/silence/watchdog 执行和普通 control 轮换不变。普通 mode 保留其现有 lease;只有额外保留需要这些短期成功授权。

原型证据:43 个 cell-registry 测试和包 typecheck 通过,包括 >12h 模拟保留且无额外周期性续期调用;6 个真实 Postgres 续期测试在本地 55440 上执行且零跳过。Baseline/revert 会使三个扩展 oracle 失败。原型注入了未来 mode 标记,并且并非生产就绪:初始采用顺序、durable mode 谓词、wire 协商和回滚仍是集成工作。本次修订只处理源续期,而不是整个保留功能。

最终续期审查更正:对失败和成功都设置围栏

新的 GPT-6-astra / low 审查:retained-control 审查,修订一个完成围栏细节;支持 heartbeat 复用。以下更正是在审查后纳入的,并非独立批准或实现。

每个续期完成以及等待恢复的继续都必须先验证其捕获的 socket/session、activity ID、当前 authority/mode 转换以及适用顺序,然后再更改调度、延长 expiry、关闭 socket 或重新获取 activity。特别是,来自已中止保留 attempt 的拒绝如果在同代 rollback 之后到达,不得关闭已恢复的源。当前适用的拒绝仍必须强制关闭。过期的 missing-activity 结果不得启动恢复;在等待恢复后,重新检查 authority,并按要求清理被放弃的获取。不要使用笼统的仅成功围栏或抑制所有失败。

为 rollback 后的迟到拒绝、更新的有效 authority 转换后的拒绝、过期的 missing-activity 恢复以及适用拒绝添加受控 promise 测试。验证保留的 socket/splice 身份和正确拒绝,而不仅仅是 expiry 值。首次授权采用还必须拒绝其请求 expiry 已经过去的成功。

在 retained-mode SQL 中,普通当前 assignment 授权替代项不得绕过 rollback 后的 aborted attempt 检查。如果锁定 attempt 行,请保持现有 rehome 操作使用的 assignment -> attempt -> migration -> activity 依赖顺序,而不是追加一个迟到的 attempt 锁。在 55440 上使用规定的 PostgreSQL 16 环境进行实现并发验证;之前六次测试的 PostgreSQL 17 运行仍应准确标记为更窄的证据。

保留代际回滚

仅进行通用源重分配是不够的:否则源单元仍然只能排水,而新的代际会关闭旧的拼接。为精确的可选尝试添加一个持久化、幂等的回滚转换。在单一权威存储事务中,分配一个更新的源纪元,并记录该尝试的回滚结果和保留的源代际。将源单元协调到该状态:仅清除该尝试的可选排水,保留其套接字/拼接,更新分配元数据,并且仅在验证当前权威后恢复新的准入。保留一个中止尝试的墓碑,以便迟到的排水无法逆转回滚。

桌面恢复必须找到/复用保留的源来源并更新其分配元数据,而无需替换其控制代际或传输。这需要一个显式支持的转换,而不是当前的“重新绑定失败 -> 新建代际”回退。迟到的目标注册不能覆盖较新的源纪元。协调完成后释放目标预留;每台主机保持一个打开的迁移,直到清理完成。如果源进程/代际已消失,使用普通的故障恢复并报告保留不可用;不要推断远程执行已退出。

转换表

状态/事件 权威与操作 现有源工作
声明可选迁移 持久化尝试绑定模式、源代际/化身、目标、纪元和支持的参与者 保留
目标注册中 源收到可选排水;现有目标重试/协调继续进行 保留;不要将年龄转换为强制关闭
目标已注册 主管目标分配具有权威性;桌面激活目标 现有源连接保留其来源
保留源需要续期 现有单元活动续期 + 精确可选迁移授权短期同代际租约延长 保留,源保持仅排水状态
目标失败/回滚 新的持久化源纪元加回滚墓碑;源单元和桌面复用精确保留的代际 如果该代际仍然存在则保留
最终源工作结束 连接和待处理工作回调注销源;取消续期;释放活动并完成 没有剩余的源工作需要保留
延迟排水/续期/注册 比较持久化尝试结果和纪元;忽略/拒绝过时转换 不得复活排水或替换代际
源失败/紧急排水 现有已认证的操作/故障语义适用 在这些故障下不承诺保留

特定模式下的持久化生命周期与兼容性下限

对于健康注册的可选保留源尝试,移除当前仅基于年龄的 24 小时租约刷新上限,并将其排除在仅基于年龄的零宽限重新排水通道之外。保持有界的目标注册失败/协调;不要无限期扩展无法到达的未注册目标。持续时间本身不是调度失败,且不得丢弃活动源数据来回收优化槽位。当前的通用和区域清理路径都必须理解可选模式。

在启用可选保留之前,部署一个理解所有持久化模式和回滚状态的主管/工作节点兼容性下限,即使新声明被禁用。操作回滚不得在有此类尝试存在时低于该下限。禁用的启用标志并不能阻止旧版清理/重新排水代码误解新行。使用现有打开的尝试和多日保留来证明安全的重启/回滚。最低修订版本仅在兼容实现合并并验证后才会记录。

额外接受的义务:在每次最终的待处理控制转换(响应、拒绝、超时、关闭)时通知退役;在等待的准入工作完成后执行最终本地会话/代际检查,并释放放弃的预留;将协商支持绑定到当前已认证的源代际,而不是过时的测量报告;在锁定的共享状态中强制执行并发迁移上限,包括既有工作。这些都不需要重建全局空闲检测器。

6. 推出与可观测性

在实现/测试期间保持重新归属(rehome)禁用。先部署兼容的主管/数据库支持,然后在功能开关关闭的情况下部署支持单元和桌面。在启用授权的有界队列之前验证就绪状态和实际能力。不要将工作流调度作为本次审查的一部分。

复用当前的速率、冷却、安全、容量、持久化尝试和失败预算控制。预览必须是只读的,共享资格谓词,报告完整的聚合计数而不是有上限的候选页面,并且绝不声明尝试或消耗预算。

按方向跟踪资格/排除、目标注册、迁移完成/中止、保留源的数量/年龄、并发预留、按排水模式统计的故意强制关闭计数,以及重连/错误率。在可用的情况下保留紧凑的采样比较和匹配的前/后分配单元/应用延迟;仅注册目标本身并不能证明用户收益。使用未变更的队列来检测无关的网络波动。绝不记录凭据、配对数据或原始主机 ID。

验收标准:受支持且符合条件的主机将新连接迁移到其选择的目标;旧数据连接存活过可选排水期限并在实际释放时退役;不因单纯优化年龄强制关闭源;资源清理干净;故障保持可恢复;采样延迟/可靠性显示出收益而无实质性回退。在生产启用前指定样本量和数值回归限制,使用可用流量,而不是在此臆造测量阈值。

7. 所需验证与实施顺序

  1. 在禁用控制下落地新鲜度/排序和相对现有者的资格支持,并附严格的请求/响应兼容性测试。用例:首次放置且纠错禁用、放置提示/实际分配不匹配、冷启动不确定探测和旧服务器回退;延迟旧报告、重复、不确定墓碑、时钟变化、重启、遗留写入、覆盖、策略升级、过时期元和缓存清除。
  2. 实现代理刷新和事件驱动的来源退役,测试无认证耦合、分配不变时无重连、待处理操作完成以及休眠/恢复。
  3. 在现有工作节点/单元/桌面路径中端到端实现协商可选排水模式,包括正常紧急期限和重放。将诊断预言机扩展为真实功能测试;不要合并定时器移除实验。
  4. 在源/目标之间验证真实 WebSocket 流量,同时发送唯一流标记和带延迟确认的变更;检查无重复/重放变更以及独立的主机端执行/输出。然后验证移动端后台/前台重连和配对保留。模拟测试不能替代端到端测试。
  5. 仅在 55440 上运行实际 Postgres 集成/并发测试。要求配置数据库、执行的测试计数且无条件跳过。覆盖注册失败、目标失败、并发准入、清理、分页和长生命周期源的容量核算。
  6. 验证支持/不支持的桌面和单元组合,以及旧/新主管回滚。SSH 托管的执行和文件夹工作区仍由传输/宿主主机管理,而非本地进程假设。不在用户桌面上运行可见应用测试;要求后台启动和隔离配置文件。
  7. 仅在已审核的推出获得授权时,运行一次全新的操作安全门和功能检查。启用一个有界队列,观察保留源/资源/收益证据,然后扩展。禁用会停止新的可选迁移,同时安全协调现有迁移。

实现修正:恢复确认可以重试

回滚响应可能在 desktop director 佐证失败时到达单元。 因此,单元会保留一个精确的待恢复权限(已中止的尝试、更新的源 epoch、原始 generation/incarnation/activity),直到普通的同代 rebind 确认恢复。每个成功的现有 heartbeat 仅续期其短暂的请求开始截止时间,并重放 region-restored。 保留权限与恢复权限互斥;回滚后,旧的保留权限仍会被拒绝。rebind、替换、紧急 drain 以及适用的 denial 会隔离未决回调。不会引入额外的 timer 或六小时 heartbeat 授权。这避免了仅仅因为首次 director 确认失败而丢失长生命周期的源连接。

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