Skip to content

fix(device-link): 修复手机连接的同步洪峰与拥塞恢复 - #4080

Merged
MagicLizi merged 4 commits into
mainfrom
dash/mobile-link-congestion-recovery
Sep 8, 2026
Merged

fix(device-link): 修复手机连接的同步洪峰与拥塞恢复#4080
MagicLizi merged 4 commits into
mainfrom
dash/mobile-link-congestion-recovery

Conversation

@dashhuang

@dashhuang dashhuang commented Sep 7, 2026

Copy link
Copy Markdown
Member

这次改了什么

摘要

修复手机连接电脑时,重复的目录同步和列表更新放大推送积压、拥塞恢复再次灌满 relay 的问题,并补齐恢复阶段的诊断证据。

  1. Library 焦点同步只处理当前焦点、仍有 Library 授权的记录和运行中的任务;运行中的 ID 独立合并,不受数据库归档、删除或可见状态影响。目录未变化时继续恢复运行时授权,但不重复落库和广播;撤销、冲突过滤及失败回滚保留。
  2. 按设备合并任务标题与只读目录更新,发送前复查连接、订阅和 owner,恢复后分批排空。引擎及生命周期字段立即发送,并吸收同任务更早的暂存字段,保持后续事件顺序。已知设备断链时暂停活动与文本镜像,恢复后先补快照。
  3. relay 1013 后,所有可靠传输的数据帧共用每 250ms 的发送预算,涵盖初发、ACK 驱动和重试;仅有 pending 数据的设备与本次目标参与设备间轮转,大分片的超额使用计入后续窗口,仅获准立即发送时才检查 socket 容量;容量拒绝或物理发送中断时退回未写帧的额度。控制 ACK/握手不占预算,本地限速不计为重试失败。
  4. 同设备、通道和错误码的重复告警保留首条及计数摘要;手机记录前台代际、连接代际、匿名设备/操作编号,以及订阅和四类快照的实际应用耗时,不记录内容、路径或错误正文。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:用户要求完整修复手机连接电脑日志审计发现的四类问题。
  • 本 PR 包含:Library 无效同步、设备镜像背压、共享 relay 拥塞恢复、低噪声诊断及回归测试。
  • 明确不包含:服务端改动、界面重设计、原生依赖和 runtime fingerprint 变更。
  • 用户可见变化:减少切换焦点和连接恢复时的重复同步;减少单设备积压对其它设备的影响。
  • 是否存在 breaking change:无。沿用现有通道、payload 和能力协商;旧版列表订阅仍可接收原格式推送。

UI 变化

不涉及。

  • 引用的设计规范:不涉及:DeviceLinkContext 的修改仅为恢复诊断和快照应用结果记录,无视觉、交互或文案变化。

怎么验证的

自动验证

env -u CINDY_AUTH_REGION -u VITE_CINDY_AUTH_REGION -u NODE_ENV \
  -u NODE_DEBUG -u CLAUDE_CODE_IDE_SKIP_AUTO_INSTALL pnpm test:unit:related
结果:通过(Desktop 全量、Mobile 全量、device-link 相关测试)。

env -u CINDY_AUTH_REGION -u VITE_CINDY_AUTH_REGION \
  bash <git-skill>/scripts/run-unit-gate.sh <worktree>
结果:ce4415702 的仓库全量单测门禁 GATE_EXIT=0;本轮小范围 review 补丁重跑上述相关门禁,Desktop/Mobile 全量和 device-link 相关测试均通过,其余未影响包沿用全量结果。

pnpm --filter desktop run --if-present typecheck
pnpm --filter mobile run --if-present typecheck
结果:均通过。
pnpm --filter @cindy/device-link run --if-present typecheck
结果:该包无 typecheck script,按仓库规则跳过。

git diff --cached --check
结果:通过。

环境与复测说明:宿主继承的 CN 区域变量曾导致 3 个未改文件共 9 项失败;同一最新主干 760005b41 精确复现,清环境后 55/55 通过。另一次全量出现未改动的 OAuth 固定端口并发用例失败,修复分支和干净主干单独运行均 41/41 通过;具体竞争原因未证实,保留原断言,最终全量复测通过。

Review 回归:最新预算单测与 DeviceLinkClient 集成测试 205 项通过,相关门禁与 Desktop typecheck 通过。此前目录同步与授权更新测试 16 项通过。回归交错用例覆盖预算耗尽且 socket 已满时初发与 ACK 驱动仍保留可靠队列、有额度时容量预检仍先于入队,以及重试容量拒绝后额度完整退回。本轮另覆盖 12 个空闲或 inbound-closed 设备不稀释活动设备额度、原空闲目标大响应首发,以及双端有 pending 时的公平分配。此前用例继续覆盖不可见但仍存活的运行时撤权、数据库已空的残留授权撤销,以及首帧/部分分片发送失败后另一设备仍可立即回复。

专项回归覆盖:2026 条重复目录更新不写库、冷运行时授权恢复与撤销、列表字段合并、引擎/删除屏障保序、慢设备与正常设备并存、可靠队列背压、迟到授权与退订取消、1013 后初发/ACK/重试共享预算、大小包混发和多设备轮转、控制 ACK 不被限速、旧客户端订阅、恢复代际隔离、快照被接受/拒绝的结果及 1990 次重复错误计数。

手工验证

完成完整 diff 自查和独立只读交叉审查,核对权限撤销、设备隔离、事件顺序与异步收尾路径。

未执行的验证

未启动该分支的手机或桌面应用,未做真实多设备弱网、手机切前后台和升级后日志对照;没有 Metro、真机或 build label 证据。工作区为 cindy-mobile-link-congestion-recovery,分支为 dash/mobile-link-congestion-recovery。自动化结果不代表已部署后的实际恢复时延。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:异步发送与拥塞恢复节奏

影响与回滚

  • 影响范围:Desktop 目录授权同步和镜像发送、共享 device-link 可靠发送、Mobile 恢复诊断。存量插件影响:无;批准记录、布局、凭证和 Library 访问规则不变,无 migration。
  • 故障半径:单设备不可写只暂停该设备镜像,不重建共享 relay;1013 是共享资源拥塞,发送预算由客户端连接统一控制;本地等待预算不消耗失败次数,控制帧可继续通过。
  • 状态边界:暂存属于设备与 owner,退订/离线/清理时丢弃,异步授权完成后再次核对当前条目和订阅;关键字段为发送屏障。快照仅在原有权限和代际检查接受后记录 applied,旧代际不记录成功。
  • 回滚 / 降级方式:回退本 PR 即恢复原发送节奏;无协议版本、数据库或原生迁移需要回退。拥塞期可能增加数据帧排队时间,大消息仍按既有协议原子分片,未设置服务端吞吐保证。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档(测试、边界和验证限制列于本 PR;无新用户操作)
  • 已确认测试结果或说明未执行原因

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@dashhuang
dashhuang requested a review from a team as a code owner September 7, 2026 21:10
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-07T22:11:55.494246Z e7dee9b New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 调整了桌面端目录授权同步和设备镜像背压,引入 relay 1013 后的共享可靠帧预算,并补充移动端恢复诊断及对应回归测试。

  • 合并任务标题和只读目录列表更新,并在断链、退订及 owner 变化时暂停或清理暂存。
  • 对 maker 事件和快照恢复增加 peer 可写状态检查。
  • 在共享可靠传输上实施按设备轮转的拥塞发送预算。
  • 聚合重复推送失败日志,并记录匿名化的移动端恢复阶段结果。
  • 目录授权避免重复持久化,同时恢复重建运行时的已有授权。

审查发现目录同步目标仍遗漏部分在运行但不属于可见 active 数据库集合的任务,可能留下过期 Library 运行时授权;此外,可靠帧发送失败时会虚扣拥塞预算。

Confidence Score: 4/5

该 PR 暂不适合直接合并,因为 Library 目录同步仍会遗漏部分正在运行的任务并可能保留过期运行时授权。

一项阻塞问题来自同步目标对运行时任务与可见 active 数据库行取交集,导致状态或来源不匹配的在运行任务无法撤销旧 Library 授权;另有一项非阻塞的拥塞预算虚扣问题,会在物理发送中断后延长其他设备的恢复等待。

Files Needing Attention: apps/desktop/src/main/maker-ipc/libraryExtraDirSyncTargets.ts, packages/device-link/src/client.ts

Important Files Changed

Filename Overview
apps/desktop/src/main/maker-ipc/libraryExtraDirSyncTargets.ts 新增 Library 同步目标筛选,但运行时 ID 仅与可见 active 数据库行取交集,遗漏状态或来源不匹配的运行中任务。
apps/desktop/src/main/maker-ipc/remoteDirectoryGrantUpdate.ts 将运行时授权恢复与持久化变更分离,避免相同目录集合重复写库,同时保留冲突过滤和回滚。
apps/desktop/src/main/device-link/dispatch.ts 新增任务列表补丁暂存、peer 可写门控及聚合失败日志,发送前的订阅、owner 和可见性复查较完整。
apps/desktop/src/main/device-link/sessionPatchStage.ts 按任务合并可延迟字段并分批排空,对背压、更新替换及 dispose 生命周期进行了处理。
packages/device-link/src/congestionSendBudget.ts 实现 250ms 共享物理帧预算、设备轮转和大消息债务结转;预算本身有界且测试覆盖公平性。
packages/device-link/src/client.ts 将初发、ACK 驱动和重试纳入共享预算,但物理发送失败时未按实际帧数修正已扣额度。
apps/mobile/src/device-link/DeviceLinkContext.tsx 为订阅和四类恢复快照接入代际隔离的匿名诊断,并仅在 store 接受结果后记录 applied。
apps/mobile/src/device-link/recoveryDiagnostics.ts 新增不记录设备标识、内容或错误正文的恢复阶段计时和前台/连接代际门控。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  DB[桌面会话数据库] --> T[Library 同步目标筛选]
  Runtime[Maker 运行中任务] --> T
  T --> Grants[应用或撤销目录授权]
  Grants --> Stage[按设备合并列表补丁]
  Stage --> Auth[发送前复查订阅、owner 与可见性]
  Auth --> Queue[可靠传输队列]
  Queue --> Budget[1013 后共享帧预算]
  Budget --> Relay[Device-link relay]
  Relay --> Mobile[移动端]
  Mobile --> Rehydrate[恢复订阅与四类快照]
  Rehydrate --> Diagnostics[匿名恢复诊断]
Loading
Prompt To Fix All With AI
### Issue 1
packages/device-link/src/client.ts:2796-2798
**拥塞预算重复计费**

这里在发送前按整条消息的 `frames.length` 扣除预算,但首帧发送失败或中途发送中断时,没有退回未发送帧的额度;后续重试还会再次按整条消息计费。WebSocket 在重连竞态中抛错时,这会产生虚假的拥塞债务,使同一连接上的其他设备在额度自然恢复前被无谓暂停,最大分片消息可能额外停顿数秒。应按实际写出的帧结算,或在失败路径退回未使用的额度。

### Issue 2
apps/desktop/src/main/maker-ipc/libraryExtraDirSyncTargets.ts:9-13
**遗漏运行中的同步目标**

`liveIds` 只在遍历可见且数据库状态为 `active``rows` 时参与筛选。因此,仍在 Maker 中运行、但数据库记录已归档、删除或来源不在可见列表中的任务不会成为同步目标。此类任务如果此前持有 Library 目录槽,在焦点或 Library 根变化后不会执行撤销,运行时会继续保留过期目录授权;这也没有实现本次修复所声明的“运行中的任务”同步范围。请独立合并符合条件的运行时 ID,或显式处理运行时状态与数据库可见状态不一致的情况。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(device-link): 减少手机同步洪峰并平滑拥塞恢复" | Re-trigger Greptile

Comment thread packages/device-link/src/client.ts Outdated
Comment thread apps/desktop/src/main/maker-ipc/libraryExtraDirSyncTargets.ts
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 33a7ea2673

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/device-link/src/client.ts
@MagicLizi MagicLizi added status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) labels Sep 7, 2026
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3e233a20d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/device-link/src/client.ts Outdated
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@MagicLizi MagicLizi removed the status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) label Sep 7, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/mobile/src/device-link/DeviceLinkContext.tsx / apps/mobile/src/device-link/recoveryDiagnostics.ts / apps/mobile/src/session/remoteSessionStore.ts)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@dashhuang

Copy link
Copy Markdown
Member Author

已核对 UI 路径提示(issuecomment-5576308609):本 PR 在 DeviceLinkContext.tsx 仅接入恢复计时与代际诊断;recoveryDiagnostics.ts 是无渲染代码的日志辅助模块;remoteSessionStore.ts 仅返回已有快照应用分支的接受/拒绝结果,供诊断记录使用。没有新增或修改 JSX 布局、样式、主题、交互及 UI 文案。按 PR 模板对“命中 UI 路径但无视觉/交互/文案变化”的豁免,正文已注明不涉及,因此不补无对应界面变化的截图或 HTML。正文仍保留未启动应用、未做实机弱网验证的限制。

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

独立审查通过:手机连接同步洪峰用连接级发送预算节流,单设备不可写只暂停该镜像,不拆共享 relay。没有 P0/P1。

@MagicLizi
MagicLizi merged commit 3fe2a5f into main Sep 8, 2026
20 of 21 checks passed
@MagicLizi
MagicLizi deleted the dash/mobile-link-congestion-recovery branch September 8, 2026 07:43
@MagicLizi

Copy link
Copy Markdown
Contributor

手机连电脑时列表同步不再把整条 relay 挤死:慢设备只暂停自己的镜像,正常设备还能回。1013 之后的数据帧也按连接预算排队,而不是无限制重放。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants