fix(device-link): 合并重复同步查询并统一两端流式恢复 - #4116
Conversation
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
| Filename | Overview |
|---|---|
| apps/desktop/src/main/device-link/dispatch.ts | 新增 250ms 补流恢复与 2 秒失败重试,但异步旧失败回调可能重置新阶段的快速定时器。 |
| apps/desktop/src/renderer/lib/makerChatStore.ts | Desktop renderer 接入共享补流消费、来源校验和流式期间的历史修复。 |
| apps/mobile/src/session/scheduleIndex.ts | 日程索引缓存新增在途失效合并及 Relay 恢复后的成功缓存失效。 |
| apps/mobile/src/session/remoteSessionStore.ts | Mobile store 改用共享文本快照识别、合并和同步包消费顺序。 |
| packages/maker-shared/src/remoteTextStream.ts | 提供两端共用的增量分类、完整快照解析、正文合并和同步包消费契约。 |
| apps/mobile/src/components/ConnectionBanner.tsx | 将普通内容同步与真实离线状态分离,并保留真实断线后的恢复尾提示。 |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
H[Desktop Host 流式事件] --> Q{peer/发送队列可用?}
Q -- 否 --> S[按 peer 暂存补流请求]
S --> T[250ms 可用性检查]
T --> Q
Q -- 是 --> F[刷新旧增量批次]
F --> P[读取最新完整文本快照]
P --> A[异步来源授权与发送准入]
A -->|成功| C[Mobile/Desktop Controller]
A -->|失败| R[2 秒失败重试]
C --> M[应用完整前缀]
M --> D[继续追加后续 delta]
C -->|resyncRequired| W[历史窗口对账]
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/main/device-link/dispatch.ts:1019-1022
**旧回调延迟新补流**
远程 bot 会话校验通过 Promise 队列异步执行,而当前循环不会等待它完成,可能先删除 session 并清理旧阶段。如果失败回调返回前,新 delta 已创建带 250ms 定时器的新阶段,这个旧回调会按 2 秒间隔重新排队,并无条件清除新阶段已有的定时器,使本可在 250ms 内发送的最新快照再次延迟约 2 秒。建议让失败回调只重排其所属阶段,或用阶段代次避免旧回调改写新阶段的计时状态。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (2): Last reviewed commit: "fix(device-link): 共用两端流式补齐与历史恢复规则" | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ffcefb4921
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ec7701dc47
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7592a1599f
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7726532600
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
MagicLizi
left a comment
There was a problem hiding this comment.
Findings
- 无 P0/P1。
Rule coverage
AGENTS.md/docs/dev-rules/development-workflow.md/.github/PULL_REQUEST_TEMPLATE.md:单一目标(合并重复同步查询、统一两端流式恢复与诊断);三大段齐全;DCO trailer 存在;未夹带无关重构/依赖/原生配置。docs/dev-rules/remote-and-mobile-adaptation.md:未新增 IPC/allowlist;故障半径三问已写在 Description(省略已有入站证明可达的探测;单请求超时与 1013 聚合背压不变;多 peer 用例覆盖一个停止 ACK 另一个继续)。共享索引在途查询不受 TTL 影响,事件失效后 settle 再合并刷新;首个页面失焦后可见等待者按自身 canStart 重入。docs/dev-rules/protocol-compatibility.md:Desktop 新声明已有session-text-snapshot-v1能力,不新增/改变 wire 字段;旧 Host 走原路径;全文快照不参与 delta 拼批。docs/dev-rules/mobile-development.md:未改原生配置/指纹输入,不触发冷更。docs/dev-rules/architecture-invariants.md:无反向 Desktop Main 依赖;main 无动态 import;布局树未改。docs/dev-rules/electron-security-and-process-boundaries.md:只读侧栏跳过sessionService.update,主窗继续持久化;日志不含正文/参数/响应。docs/dev-rules/engineering-conventions.md:诊断日志走统一 logger,短 ID / 队列深度 / 等待时长,无敏感样例。docs/product-rules/core-product-principles.md:普通在线切任务不再误报“正在同步→已恢复”;真实断线 1.2s 防闪与恢复尾提示保留。docs/design-rules/DESIGN.md:沿用语义 token 与既有 banner 组件;无硬编码色/新组件。UI 证据缺失(截图/录屏)为非阻断提醒,作者已声明未做实机 Light/Dark 目检。- 讨论 thread 均已 resolve;先前 P1(后台重试、共享索引交接、终态正文接管)已在 head
ac050761b落实。
Verification
git diff --check:EXIT=0pnpm install --frozen-lockfile(本审查 worktree):EXIT=0pnpm --filter mobile exec vitest run7 个相关文件:100 passed,EXIT=0pnpm --filter desktop exec vitest rundispatchMakerEventBatch / dispatchWeakNetwork / deviceLinkControllerScenarios / makerChatStoreTextDeltaBatching:284 passed,EXIT=0pnpm --filter @cindy/device-link exec vitest run src/__tests__/client.test.ts:207 passed,EXIT=0pnpm --filter @cindy/maker-shared exec vitest run src/__tests__/remoteTextStream.test.ts:3 passed,EXIT=0pnpm --filter mobile typecheck:EXIT=0pnpm --filter desktop typecheck:EXIT=0@cindy/device-link/@cindy/maker-shared无 typecheck script,已跳过- GitHub CI:client-ci / pr-design-basis / PR #4116 均为 success
- 未执行:实机弱网、前后台切换、Light/Dark 目检(作者已声明)
- botSettle:已等 ≥20 分钟超时放行;copilot-pull-request-reviewer / chatgpt-codex-connector 可能在合并后才到
Overall
pass:没有 P0/P1。
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74f3a3a0bf
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67d14eeb8f
ℹ️ 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".
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c76f70120a
ℹ️ 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".
| if (maker.schedule.listSidebarIndexRuns) { | ||
| try { | ||
| return buildLightweightSessionScheduleIndex(await maker.schedule.listSidebarIndexRuns(), schedules); |
There was a problem hiding this comment.
当同一任务关联的多个自动化并发运行、较新的 run 已终态而较旧的 run 仍在运行时,这里改为优先使用 listSidebarIndexRuns() 会漏掉运行标记:SchedulerStorage.listSidebarIndexRuns() 会刻意清除非最新 running 行的 sessionId,而 buildSessionScheduleIndex() 直接跳过没有 sessionId 的行。旧的逐 schedule listRuns 路径保留了该归属,因此冷启动或漏过 fired 推送后仍能显示任务正在运行;现在首页、设备详情和抽屉都会把该任务显示为空闲。请让轻量快照为 Mobile 提供这些在途 run 的会话归属,或在构建索引时结合 inflightPolicies 恢复映射。
Useful? React with 👍 / 👎.
这次改了什么
摘要
手机进入普通任务时,已读探测绕过首页已有缓存,重新查询全部定时任务及运行记录;页面留在导航栈里也会继续响应事件。在弱网下,原缓存超过 30 秒还会对尚未完成的查询再启动一轮,增加同步队列压力。
本次让首页、设备页、任务页和任务列表抽屉复用同一份在途查询,事件统一使缓存失效,旧查询结束后再合并刷新。Relay 重连或回前台时,在共享恢复入口失效旧成功索引,补查断线期间漏掉的完成事件;保留设备离线、熔断及超时负缓存。后台页面不再启动查询或标记已读,已读回推不再触发任务页重复扫描。有效入站消息已经证明 relay 可达时,省去紧随网络变化提示的冗余探测。
共享查询保留完整定时任务元数据,运行记录优先复用已有轻量索引接口;旧 Host 不支持时回退原串行查询,保留零运行记录的绑定、暂停状态和历史失败提示。
另外修复同步事件在只读侧栏中误调用数据库写接口的问题:侧栏更新显示镜像,主窗口继续负责持久化。补充手机请求与电脑执行、发送排队的关联日志,并区分接收容量不足、分片超限和声明长度错误。日志不包含消息正文、参数或响应内容。
手机文字暂停增量后,原补快照定时器固定等待 2 秒,队列已经恢复也要等下一次检查。本次复用同一计时器,将 peer/队列可用性检查缩短为 250 毫秒;实际读取或发送快照失败仍按原来的 2 秒间隔重试。始终先补最新完整前缀,再继续增量;增加不含正文的补发排队和准入日志。
Desktop 远程端与 Mobile 共用增量分类、完整文本快照识别/替换和同步包消费顺序;Desktop 完整接入接收后声明已有的 session-text-snapshot-v1 能力,两端由同一 Host 补发路径恢复。平台适配负责来源校验、store 写入、历史对账和通知,不新增 wire、发送队列或恢复计时器。历史按需加载和正文交接沿用主干已合并的 #4081。补流对账兼容新投影接口与旧 Host 历史接口:同身份正文在读取期间未更新时可接管残留流式行,新增量仍优先。
普通进入任务时,内容同步不再被当作断线来显示“正在同步→已恢复”横幅。提示呈现沿用主干 #4191:普通同步使用标题动画,真实错误、设备未响应与手动恢复入口保留,恢复完成不再额外提示。
变更类型
fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
UI 变化
docs/design-rules/DESIGN.md§2(语义主题)与 §14.4(功能性状态反馈)。普通在线页面切换不再显示误导性的恢复横幅;沿用主干 fix(mobile): 普通同步使用延迟标题动画,异常保留悬浮提示 #4191 的统一 3 秒防闪窗口、普通同步标题动画与完成立即隐藏规则。沿用主干浮层布局、Light/Dark 语义样式、减弱动态设置和手动恢复按钮;相对主干不改变布局、颜色或文案。怎么验证的
自动验证
在独立工作区执行,清除继承的
CINDY_AUTH_REGION、VITE_CINDY_AUTH_REGION、NODE_ENV:此前主干冲突收敛:沿用主干浮层与单一延时状态,保留普通在线同步不触发恢复提示。7 项横幅回归、根自动全量、统一 full unit、两端类型检查及 Mobile scope/smoke 通过。
此前可见消费者交接修复:旧页面失焦取消重试后,已加入等待的新页面在请求结束时复查失效标记,沿现有缓存使用自己的可见性条件接手;不新增消费者注册表、计时器或重试层。68 项定向回归通过;提交前相关门禁和 Mobile 类型检查通过。
回归覆盖:在途查询超过 TTL 仍共享;事件失效后只合并一轮刷新;每次有界重试前检查可见性,取消不进入负缓存;轻量索引与旧 Host 回退均保留完整绑定、暂停状态和历史失败;抽屉后台不重试/扫描,回前台恢复。
补流覆盖新投影/旧历史接口 × 读取期间有无新文字四种交错,并断言最终 HistoryViewHandoff 正文。终态推送丢失时补回完整正文并清除消息流式标记;并发增量及历史未覆盖的行保留。缓存的工作详情不作为新鲜正文接管的依据。
既有 Host 用例覆盖逐条/批次发送、peer/队列阻塞恢复后的 250ms 快速复查、实际读取/准入失败的 2s 重试,以及旧阶段迟到失败不延后新阶段计时器。共享客户端覆盖队列顺序恢复、多 peer 故障隔离、只读侧栏与主窗口持久化边界、日志不含敏感样例。横幅用例保留真实断线/错误/手动恢复,普通在线切换不闪恢复提示。
横幅合并不变量:完全复用主干 #4191 的提示组件和共享延时 hook;普通 connecting/syncing 不启动异常浮层,真实离线或错误才启动三秒防闪计时,恢复即隐藏,不恢复旧两秒尾提示。标题摘要不一致的立即反馈沿用主干 immediate 参数,未新增状态或计时器。
设备详情页可见性不变量:首次仍先加载任务列表;列表成功后的索引取消不依赖日程事件才能恢复。索引 effect 沿用现有 lastSyncedAt,由 syncSessions 成功路径写入;重新聚焦、回前台或事件均重入同一共享缓存,不可见时不启动扫描。索引成功/失败和在途交接仍由现有缓存负责,不新增状态、重试或计时器。新回归执行实际页面 effect 与真实缓存,旧代码的失焦/后台两例失败,修后通过,并覆盖首拉顺序、在途单飞和成功 TTL 复用。
本轮设备详情恢复修复:59 项定向用例、Mobile typecheck 与最终根相关门禁通过。根门禁首次有一项未改动的更新器用例偶发失败,该文件在同基线 main 与本分支单独运行各 69 项通过,随后根门禁复验 exit 0。此前合并后的统一 full unit GATE_EXIT=0,本次两文件小修由相关门禁复验。
此前合并 main 240e702:测试插入位置冲突保留双方用例,无额外业务逻辑修改;175 项文字流测试、两端类型检查及最终根相关门禁通过。首次根门禁一项未改动 ASR WebSocket 用例收到 socket hang up,当前分支和本地主干单独各 19 项通过,根复验 exit 0,未修改语音代码。
历史视图恢复不变量:停用视图不在后台启动补查;每次恢复沿原有读取同步执行未变化流式行的正文交接,覆盖后台收到补流信号、读取中离开和首拉未 ready 的情况。可见性仍由 HistoryViewController 持有,正文交接仍用既有引用身份保护;离开令旧读取代失效,重入沿既有队列获取当前代结果,不记录额外 repair 状态。旧 Host raw 路径不变。
本轮停用历史视图修复:旧代码复现恢复后正文仍缺尾;最终 82 项控制端/活动视图用例、Desktop typecheck 与根相关门禁通过。复用此前 full unit 结果,本次两文件小修由相关门禁复验。
最新合并 main e80bfcc(#4191):提示组件沿用主干实现,删除本分支旧恢复尾提示;8 项提示回归、两端类型检查及根相关门禁(Desktop/Mobile/maker-core 等全包)exit 0。未增加业务机制,保留全部查询与流式修复。
手工验证
通过既有手机与电脑诊断记录定位问题,未把修改安装到日常使用实例。
未执行的验证
未进行修改后的实机弱网、前后台切换与 Light/Dark 目检。未启动本分支 Metro 或生成本分支手机 build label;自动化测试不代表实机同步停滞已完全解决。
风险
风险分类
影响与回滚
executionWaitMs表示电脑执行等待,queuedMs表示回复本地排队;手机接收日志含预期序号与队列大小。一次请求变慢仍不能直接推断电脑主进程卡死,需要两端请求编号和时间线交叉验证。session sync repair queued/admitted记录短 peer/session 编号、队列深度、可写状态、补发阶段耗时和是否需要重拉历史;admitted 仅表示进入发送链,不等于控制端已收到或显示。跨端比较需结合控制端接收/渲染日志,不直接相减未校准的时钟。提交前检查
git commit -s,pnpm check:dco通过)