purpose
diff path に per-commit の file 上限が無く、file 数の多い commit が単独で Worker の 1 invocation あたり subrequest 予算(1000)に迫りうる。#236 が閉じた token 軸と同じ形で diff surface が恒久停止する経路なので、file 数軸にも上限を入れる。
premise
Too many subrequests by single Worker invocation は仮説ではなく、この worker の production で現に発生している(#236 本文の観測、および wiki 取得経路 fetchWikiContent)。
per-file のコストは src/pipeline/embed-diff.ts で 2 subrequest。
upsertFtsRow(D1 FTS mirror)— L235
storeStub.fetch(Durable Object への DiffRecord 記録)— L295
これに batch 単位のコストが加わる。1 batch あたり 2 subrequest(Workers AI call と VECTORIZE.upsert)。GitHub の commit detail API は 1 commit あたり最大 300 file を返す。
src/poller.ts の cap は commit 数にしか掛かっていない。
MAX_DIFF_COMMITS_FORWARD_PER_RUN = 5
MAX_DIFF_COMMITS_BACKWARD_PER_RUN = 5
file 数側の cap は diff path のどこにも存在しない。しかも cron 1 tick は 1 invocation で全 repo・全 surface を処理するため、subrequest 予算は docs / wiki / issue / release 経路と共有されている。
なぜ stall するか
#178 の watermark 不変条件により、取り込みに成功していない commit を watermark は追い越さない。subrequest 枯渇で file の upsert が失敗すると failed に計上され、その commit は未取り込みとして扱われる。file 数が原因である以上、次の cron でも同じ commit が同じ file 数で再試行されるので、失敗は決定論的。#236 で修正した token 軸とまったく同じ停止の形になる。
不変条件側は正しい。上限を持たない側が欠陥である。
constraints
- watermark 不変条件は変更しない
- file を落とさない。上限は「1 run で処理する file 数」の分割であって、間引きではない。1 commit を複数 run にまたがって処理する場合、その commit の watermark は完了まで前進させない(不変条件と整合させる)
- subrequest 予算は invocation 全体で共有されているため、diff path だけの局所最適にしない。少なくとも「diff path が予算をどれだけ使ってよいか」を明示する形にする
- 要件記述(
docs/0-requirements.md / docs/0-requirements.ja.md)を同一 PR で更新する
target files
src/poller.ts — per-commit file 上限と、部分処理時の watermark 保持
src/pipeline/embed-diff.ts — 呼び出し側の分割受け入れ
docs/0-requirements.md / docs/0-requirements.ja.md — Diff Pipeline 節
- テスト — 上限超過 commit が分割され、完了まで watermark が前進しないこと
acceptance
- file 数の多い commit が単独で invocation 予算を使い切らない
- 部分処理された commit の watermark が前進しない
- 既存テストが通り、回帰テストが追加されている
経緯
#236 の実装中に 2 回にわたり報告された隣接ギャップ。#236 の literal 外のため分離した。
purpose
diff path に per-commit の file 上限が無く、file 数の多い commit が単独で Worker の 1 invocation あたり subrequest 予算(1000)に迫りうる。#236 が閉じた token 軸と同じ形で diff surface が恒久停止する経路なので、file 数軸にも上限を入れる。
premise
Too many subrequests by single Worker invocationは仮説ではなく、この worker の production で現に発生している(#236 本文の観測、および wiki 取得経路fetchWikiContent)。per-file のコストは
src/pipeline/embed-diff.tsで 2 subrequest。upsertFtsRow(D1 FTS mirror)— L235storeStub.fetch(Durable Object への DiffRecord 記録)— L295これに batch 単位のコストが加わる。1 batch あたり 2 subrequest(Workers AI call と
VECTORIZE.upsert)。GitHub の commit detail API は 1 commit あたり最大 300 file を返す。src/poller.tsの cap は commit 数にしか掛かっていない。MAX_DIFF_COMMITS_FORWARD_PER_RUN = 5MAX_DIFF_COMMITS_BACKWARD_PER_RUN = 5file 数側の cap は diff path のどこにも存在しない。しかも cron 1 tick は 1 invocation で全 repo・全 surface を処理するため、subrequest 予算は docs / wiki / issue / release 経路と共有されている。
なぜ stall するか
#178 の watermark 不変条件により、取り込みに成功していない commit を watermark は追い越さない。subrequest 枯渇で file の upsert が失敗すると
failedに計上され、その commit は未取り込みとして扱われる。file 数が原因である以上、次の cron でも同じ commit が同じ file 数で再試行されるので、失敗は決定論的。#236 で修正した token 軸とまったく同じ停止の形になる。不変条件側は正しい。上限を持たない側が欠陥である。
constraints
docs/0-requirements.md/docs/0-requirements.ja.md)を同一 PR で更新するtarget files
src/poller.ts— per-commit file 上限と、部分処理時の watermark 保持src/pipeline/embed-diff.ts— 呼び出し側の分割受け入れdocs/0-requirements.md/docs/0-requirements.ja.md— Diff Pipeline 節acceptance
経緯
#236 の実装中に 2 回にわたり報告された隣接ギャップ。#236 の literal 外のため分離した。