fix(poller): cap pollDocs / pollReleases fan-out to fit Worker subrequest budget (#149)#150
Merged
liplus-lin-lay merged 1 commit intoMay 7, 2026
Conversation
…uest budget PR #144 で `pollComments` の per-repo per-run fetch cap を 10 に引き下げて以降、`:15` cron は安定したが、`:00` LIGHT_CRON で `pollDocs` / `pollReleases` / `pollRepo` を 5 repos 直列に走らせる side が同 root cause で `Too many subrequests by single Worker invocation` を出している (issue #149, 2026-05-07 00:01 JST 観測, 24h で 90 errors)。 LIGHT_CRON は 1 Worker invocation で 5 repos x 3 surfaces を共通の 1000-subrequest budget で回す。1 doc fetch / 1 release upsert あたり ~5 subrequests (Workers AI embed + Vectorize upsert + D1 FTS upsert + Store DO + GH API) を消費するため、surface 内で fan-out cap が無いと一発で 1000 を超える。 本 PR で `MAX_DOC_FETCHES_PER_REPO_PER_RUN = 10` と `MAX_RELEASE_UPSERTS_PER_REPO_PER_RUN = 10` を `src/poller.ts` に追加し、PR #144 と同じ shape (warn log + per-repo counter) で運用する。worst-case 計算: 5 repos x 10 items x ~5 subrequests = 250 / surface, 3 surfaces x 250 = 750 subrequests, 1000 budget に対し 250 の余裕。 ETag watermark の取り扱いも合わせて修正: cap で run を打ち切った場合に新 ETag を保存すると次回 cron が 304 で短絡して未処理分を見落とすため、cap exhausted のときは prior storedEtag を保持 (lastPolledAt のみ更新)。`pollDocs` / `pollReleases` 双方で同様。 Refs #149
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
github-rag-mcp | e598843 | May 07 2026, 02:01 AM |
liplus-lin-lay
commented
May 7, 2026
Member
Author
liplus-lin-lay
left a comment
There was a problem hiding this comment.
AI 自己レビュー (auto mode)
検証済み項目
実装パターン整合性
- PR #144 (
MAX_COMMENT_FETCHES_PER_REPO_PER_RUN, commit2711932) の cap shape と一致: 定数定義 + counter 変数 + warn log + 越境ループ break。pollCommentsのfetchBudgetExhaustedflag pattern をpollDocs/pollReleases双方に転用。 - 数値設計 (10 = 800 subrequests / 5 repos / 3 surfaces / ~5 subreq-per-item) を src コメント + commit body + PR body 3 箇所で worst-case math 付きで明示。
ETag watermark 取り扱い
pollDocs/pollReleases双方で cap exhausted 時に新 ETag を保存しないルートを追加。新 ETag を保存すると次回 cron が 304 短絡して未処理 doc / release を永続的に見落とす副作用を排除。- prior
storedEtag保持 +lastPolledAt更新で run 観測性は維持。
budget 順序
pollReleasesで新 cap をMAX_EMBEDDINGS_PER_RUNチェックの手前に配置。change-detection 段階の Store DO subrequest も bound する設計判断を src コメントに記載。
ビルド検証
npx tsc --noEmit通過 (clean exit)。npx wrangler deploy --dry-run通過 (Total Upload 2226.23 KiB / gzip 378.17 KiB, 全 binding 解決)。- GitHub Actions CI:
testpass,CIgate pass, Workers Builds pass。
docs check
docs/0-requirements.md/docs/0-requirements.ja.mdをMAX_COMMENT_FETCHES/MAX_DOC/MAX_RELEASE/pollDocs/pollReleases/subrequest/fetch budget/PER_REPO_PER_RUNで grep。MAX_WIKI_EMBEDDINGS_PER_RUNの数値言及 + LIGHT_CRON / COMMENTS_CRON / DIFFS_CRON / WIKI_CRON の cron 構成記述はあるが、pollDocs / pollReleases 個別 cap の数値仕様は不在。docs 更新不要と判断。
検証できなかった項目
- 本番 traffic 下での 1000-subrequest budget 実測: 計算上は 750 subrequests 想定だが、busy repo (e.g.
dipper_ai) の実 LIGHT_CRON で per-cron 実測値は merge 後 24h Observability で要確認。pollCommentsの #134 → PR #144 で 30 → 10 を 1 段階で済ませた前例があるため、10 で初期投入 → 観測 → 必要なら段階的に下げる方針。 - ETag 保留パスの実 304 short-circuit 回避: 単体ロジックは確認したが、Store DO の watermark 永続化が
etag: storedEtag(undefined になる初回 fetch path 含む) で正しく書き戻るかは run-time で要確認。storedEtagが undefined ならば次 cron は無条件 fetch なので機能上問題なし。
残留リスク
- cap=10 は
pollCommentsの 1 段階目 (cap=30) と同等の保守性: 仮に 10 でも溢れる構造的問題があれば PR #144 と同じく追加引き下げが必要。fan-out 計算 (~5 subreq/item) は釘刺し前提値で、実 traffic で 7-8 subreq/item に振れる場合は 5 repos × 10 × 8 = 400/surface × 3 = 1200 で再 overflow 余地あり。 - 持ち越し挙動の負荷分散: 大量 changed
.mdがある repo (e.g. docs 一括 reorg) で毎時 10 docs しか処理できない → 100 docs 変更で 10 cron run = 10 時間。許容範囲だが緊急 indexing 用途の手動 trigger は別途必要になる可能性。 MAX_EMBEDDINGS_PER_RUN = 50の実効性: 新 cap (10) が常に手前で発火するため、MAX_EMBEDDINGS_PER_RUNの per-surface 50 は事実上 dead code 化。後続 PR で整理候補 (本 PR 範囲外, follow-up issue 候補)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #149
背景
PR #144 で
pollCommentsの per-repo per-run fetch cap を 30→10 に下げて:15cron は安定したが、:00LIGHT_CRON でpollDocs/pollReleases/pollRepoを 5 repos 直列に走らせる側で同 root cause が独立に発生していた。2026-05-07 00:01 JST に Cloudflare Workers Observability でToo many subrequests by single Worker invocationが直近 24h で 90 件発火、Failed to poll docs for {repo}/Failed to poll releases for {repo}/Failed to poll {repo}の 3 surface 全てで観測。変更内容
src/poller.ts:MAX_DOC_FETCHES_PER_REPO_PER_RUN = 10を新設し、pollDocsの changed-entry ループにfetchesIssuedcounter + warn log を追加 (PR fix(poller): lower pollComments cap from 30 to 10 to fit Worker subrequest budget #144 /MAX_COMMENT_FETCHES_PER_REPO_PER_RUNと同 shape)。MAX_RELEASE_UPSERTS_PER_REPO_PER_RUN = 10を新設し、pollReleasesの release ループにupsertsIssuedcounter + warn log を追加。既存MAX_EMBEDDINGS_PER_RUN(50) より手前に新 cap を置き、変更なし release の change-detection subrequest も含めて bound する。storedEtagを保持しつつlastPolledAtだけ更新する。subrequest 予算の見積もり
LIGHT_CRON は 1 Worker invocation で 5 repos × 3 surfaces を 1000-subrequest budget 共有で実行。1 item あたり ~5 subrequests (Workers AI embed + Vectorize upsert + D1 FTS upsert + Store DO + GH API)。
worst-case: 5 repos × 10 × ~5 = 250 / surface, 3 surfaces × 250 = 750 subrequests, 1000 budget に対し 250 の余裕。pollComments (PR #144) と同じ envelope。
観測
pollComments側 (bug(poller): pollComments exhausts Worker subrequest budget on dipper_ai #134 / PR fix(poller): lower pollComments cap from 30 to 10 to fit Worker subrequest budget #144) は:15cron でfetch budget reached (10 fetches)warn のみ・errors 0 で安定確認済み。本 PR で:00LIGHT_CRON も同じ動作 (pollDocs: fetch budget reached for {repo} (10 doc fetches)/pollReleases: upsert budget reached for {repo} (10 releases)) に揃える。blobShaが store 上で未更新のため次回 cron でchangedEntriesに再出現、release は emptybodyHashで store 保存されているため次回 cron で再処理 (既存 pattern 踏襲)。docs check
docs/0-requirements.md/docs/0-requirements.ja.mdにMAX_WIKI_EMBEDDINGS_PER_RUNの数値言及はあるが、pollDocs/pollReleases個別 cap の数値仕様は無く、subrequest 予算の架構レベル記述のみ。docs 変更は不要 (確認済み)。related
pollCommentsside, resolved)