跳转至

[ISSUE-0028] doResumeFromInterception 只调 manageQueue 漏地图调度

相关源码src/entrypoints/background/batch-controller.ts:911-924 v0.10.40 引入;v0.10.44 修复(由独立 audit agent 发现)

根因

v0.10.40 的 doResumeFromInterception 末尾只调用 manageQueue()

// v0.10.40 ❌
export async function doResumeFromInterception() {
  // ... 改 globalStatus + task.status + persist
  manageQueue();  // 仅 engine-manager 的官网调度
}

但项目有两套调度: - engine-manager.ts:manageQueue() —— 处理 website 任务(独立 worker) - batch-controller.ts:pumpScheduler() + pumpPager() —— 处理 maps 任务(共享窗口 tab)

所以拦截恢复后: - ✅ website 任务能重启 - ❌ maps 任务的 paging job 不会重新派

对照 resumeBatch:735-736 的正确模式:

// resumeBatch 末尾
await pumpScheduler();
await pumpPager();

v0.10.40 没复用这套,漏调 = 纯地图任务的自动恢复无效。

谁发现的

独立 audit agent(general-purpose subagent)跑 fresh-eyes review 时发现。我自己做的 4 轮 review 都没发现 — 因为我聚焦"用户感知 / 状态机 / 持久化",没回到"调度路径完整性"这个角度。

修复

export async function doResumeFromInterception() {
  // ... 原有逻辑
  manageQueue();           // engine-manager 网站调度
  await pumpScheduler();   // batch-controller 地图当前 task 派 tab
  await pumpPager();       // batch-controller 地图 paging job 派
}

验证

  • pnpm compile 0 错
  • pnpm build 8.12s
  • 浏览器实测路径:
  • 创建纯地图任务(不带 website)
  • 触发拦截(如反爬)
  • 完成验证 / 点"我已验证完"
  • 30s 冷却后 alarm 触发 doResumeFromInterception
  • 预期:地图 task 重新派 tab 继续抓
  • 修复前:地图 task 卡住不动(因为只调了 manageQueue)

如何避免再犯

  • 写恢复 / 重启逻辑时复用已有的"正确模式" —— resumeBatch 已经是 canonical 实现,doResumeFromInterception 应该照抄
  • 不要假设"manageQueue 等于全启动" —— 它只是 engine-manager 的网站调度
  • 独立 audit 是必要的 —— 自己写的代码自己复审有盲区,跨视角才能发现

复盘:4 轮自己 review 漏掉,独立 agent 一次发现

轮次 关注角度 发现这个 bug 吗
v0.10.38 自己新代码
v0.10.40 MV3 持久化 ❌(修了 verifyTabId 但没看调度路径)
v0.10.41 跨模块同款
v0.10.43 数据完整性 / 错误处理
独立 agent fresh eyes 重点查"调度路径" ✅ 一次找到

根本原因:我做了 v0.10.40 这段代码,反复 review 时仍按"我当初的思路"看,没意识到"manageQueue ≠ 全启动"。独立 agent 没有这个 anchor,能客观对比 resumeBatch 模式。

教训:自己写的关键代码必须由"没参与原始实现的人"或"独立 agent"复核。

相关

  • [[0026-captcha-resume-sw-restart-lost-state|0026-拦截恢复SW重启丢状态]] — v0.10.40 引入这段代码
  • 共享队列架构 — 两套调度的设计语义