baa-conductor

git clone 

baa-conductor / plans
codex@macbookpro  ·  2026-04-01

OPT-007-DISPATCHER-JITTER.md

 1# OPT-007: Renewal dispatcher 加入随机抖动避免限流
 2
 3日期:`2026-03-30`
 4优先级:`P2`
 5状态:`completed`
 6
 7## 背景
 8
 9当前 renewal dispatcher 在一个 tick 内连续派发多个 job 时,请求之间没有任何延迟,可能在短时间内向同一平台发出大量请求触发上游限流。此外,重试退避使用纯指数计算(`baseDelay * 2^n`),多个 job 在同一时刻失败后会在完全相同的时间点重试,形成 thundering herd。
10
11浏览器请求链路本身已经有 `browser-request-policy` 的 Gaussian jitter(1~5s),但 dispatcher 层面的批量派发和重试调度不受该策略控制。
12
13## 需求
14
15### 1. Inter-job jitter
16
17同一 tick 内连续 dispatch 多个 job 时,从第二个 job 起在派发前加入随机等待。
18
19- 默认区间:`500ms ~ 3000ms`(均匀分布)
20- 可通过 options 配置 `interJobJitterMinMs`、`interJobJitterMaxMs`
21
22### 2. Retry backoff jitter
23
24在现有指数退避基础上叠加随机偏移,防止多个 job 在同一时间点重试。
25
26- 默认 jitter factor:`±30%`
27- 计算方式:`baseDelay * 2^n ± (baseDelay * 2^n * jitterFactor * random)`
28- 可通过 options 配置 `retryJitterFactor`
29
30### 3. 可测试性
31
32- 新增 `random?: () => number` option,测试时注入确定性随机源
33- 现有测试不应因抖动引入 flaky
34
35## 改动范围
36
37`apps/conductor-daemon/src/renewal/dispatcher.ts`38
39- 新增常量:`DEFAULT_INTER_JOB_JITTER_MIN_MS`、`DEFAULT_INTER_JOB_JITTER_MAX_MS`、`DEFAULT_RETRY_JITTER_FACTOR`
40- `RenewalDispatcherRunnerOptions` 增加 `interJobJitterMinMs`、`interJobJitterMaxMs`、`retryJitterFactor`、`random`
41- `runRenewalDispatcher` 主循环在连续派发之间插入 sleep
42- `computeRetryDelayMs` 增加 jitter 偏移
43- 新增 `sampleUniformJitterMs`、`sleep` 辅助函数
44
45## 不需要改动的地方
46
47- `browser-request-policy.ts`:已有独立的 Gaussian jitter,不重复
48- `instructions/loop.ts`:指令走本地 API 然后经 browser-request-policy,已有抖动
49- schema / 数据库 / API 端点:无变化
50
51## 验收标准
52
53- 单 tick 内 3+ job 时,第 2/3 个 job 的 dispatch 时间与前一个有可观测的随机间隔
54- 两个相同 attemptCount 的 failed job 重试时间不完全相同
55- 现有 dispatcher 测试全部通过
56- `random` option 可注入,测试可使用固定种子验证抖动范围
57
58## 完成摘要
59
60- 完成时间:`2026-04-01`
61- 实现位置:`apps/conductor-daemon/src/renewal/dispatcher.ts`
62- 实际落地:
63  - 新增集中式 jitter 配置:`interJobJitterMinMs`、`interJobJitterMaxMs`、`retryJitterFactor`、`random`
64  - 同一 tick 内从第 2 个实际 dispatch 起,在发送前统一走 inter-job jitter
65  - retry 继续保留原有指数退避和 max-delay 语义,只在其上叠加可控 jitter 偏移
66  - dispatcher 日志新增 inter-job jitter 记录,并在 `job_retry_scheduled` 中输出 `retry_base_delay_ms`、`retry_delay_ms`、`retry_jitter_ms`
67- 验证:
68  - `pnpm -C apps/conductor-daemon test`