Skip to content

fix(wiki): let the pass's first page finish its probe so the cursor advances [poller, docs, tests] - #198

Merged
liplus-lin-lay merged 1 commit into
mainfrom
192-bugwiki-a-limit-smaller-than-one-pages-probe-count-stalls-the-walk-cursor
Aug 2, 2026
Merged

fix(wiki): let the pass's first page finish its probe so the cursor advances [poller, docs, tests]#198
liplus-lin-lay merged 1 commit into
mainfrom
192-bugwiki-a-limit-smaller-than-one-pages-probe-count-stalls-the-walk-cursor

Conversation

@liplus-lin-lay

Copy link
Copy Markdown
Member

Closes #192

変更内容

pollWiki の walk に「その pass で 1 page も visit していない間は、予算より候補リストの試し切りを優先する」を入れた。

  • visited === 0 の間は fetchWikiContentfetchBudget - fetches ではなく Number.POSITIVE_INFINITY を渡す(src/poller.ts
  • 予算切れ break の条件に visited > 0 を足した。先頭 page の probe は打ち切られないので、そこでの miss は候補を全て観測した上での 404。従来どおり visited++ / nextCursor 前進 / failed++ の経路に落ちる
  • visited >= 1 以降の予算判定と break は一切変えていない
  • WikiPollSummary.fetches の doc comment を更新(先頭 page に限り予算を超えうる)
  • docs/0-requirements.md / .ja.md に「先頭 page では予算より候補リストを優先する」段落を追加、docs/installation.md / .ja.md の運用ノートに fetcheslimit を最大 3 超える条件を追記

なぜ

walk は、page の候補拡張子を試し切る前に予算が尽きた場合、visited++ / nextCursor 前進の手前で break する。観測していない失敗を failure として計上しないための #185 由来の判断。

このとき cursor は動かない。予算が次回 pass でその page の候補数を上回るなら自己修復するが、limit 自体が 1 page の候補探索回数を下回ると、何回呼んでも同じ page の手前で break し続けて walk が永久に停止する。1 page あたりの候補数は WIKI_EXTENSIONSmd / markdown)× ファイル名候補(rawName != slug の page で 2)で最大 4 なので、停止条件は limit=1 に限らず limit < その page の候補数 で成立する。

#185 の判断(観測していない失敗を計上しない)は維持している。先頭 page は候補を試し切ってから 404 と判定するので、計上する失敗は実際に観測したものだけという性質は変わらない。

設計判断

endpoint 側で limit の下限を引き上げる案は採らなかった: 直る範囲が /admin/backfill-wiki の入口だけで、fetchBudget を直接渡す他の呼び出し(cron 経路含む)に同じ停止が残る。入口の validation は不変条件の置き場所として弱い。

拡張子探索状態を次 pass に持ち越す案も採らなかった: 永続状態が増える一方、得られる前進保証は採用案と同じ。

超過量: 1 pass あたり最大 候補数 - 1 = 3 subrequest。invocation あたり 1000 の予算に対して無視できる範囲で、かつ pass ごとに 1 回だけ。fetches が予算を超えうる唯一のケースなので docs に明記した。

テスト

src/poller-wiki.test.ts に describe 1 本 / test 3 本を追加:

  • limit=1 で繰り返し呼んだとき walk が前進する(cursor が p1p2p3 と進み、各 pass の visited は 1、fetches は 2)— 受け入れ条件 1
  • 候補を全て 404 で観測した page は failed に計上され cursor も前進する(4 attempts、nextCursor が当該 page に進む)— fix(wiki): resume the page walk from a cursor so every page is reachable [poller, admin, docs, tests] #185 の判断を壊していないことの固定
  • visited >= 1 以降は予算超過が起きない(先頭 Home の後、p1 は 1 attempt で打ち切られ fetches は予算どおり 2、failed は 0 のまま cursor は Home に留まる)— 受け入れ条件 2

修正を戻すと前 2 本が落ち、3 本目は前後どちらでも通る(不変条件側の固定なので意図どおり)ことを確認済み。

ローカル確認: npm test(node 102 / workers 53、全 green)、npx tsc --noEmitnode scripts/check-schema-drift.mjsnpx wrangler deploy --dry-run --outdir dist

…dvances [poller, docs, tests]

`pollWiki` の walk は、予算切れで page の候補リストを試し切れなかった場合に
`visited++` / `nextCursor` 前進の**手前**で break する。観測していない失敗を
failure として計上しないための #185 由来の判断で、これ自体は維持する。

ただし break したとき cursor は動かないので、`fetchBudget` が 1 page の候補数
(`md` / `markdown` × ファイル名候補 2 = 最大 4)を下回ると、次の pass も同じ
page の手前で break し続け、walk が永久に前進しない。`/admin/backfill-wiki` の
`limit` は 1 から受け付けるため、`limit < その page の候補数` で成立する。

その pass でまだ 1 page も visit していない間(`visited === 0`)は候補リストを
予算より優先し、先頭 page だけ probe を試し切らせるようにした。そこで
`fetched` が null なら候補を全て観測した上での 404 なので、従来どおり
`visited++` / cursor 前進 / `failed++` に落とす。`visited >= 1` 以降の予算判定と
break は一切変えていない。

超過は 1 pass あたり最大 `候補数 - 1` = 3 subrequest で、invocation あたり
1000 の予算に対して無視できる範囲。pass ごとに 1 回だけ。

endpoint 側で `limit` の下限を上げる案は採らなかった。直る範囲が入口だけで、
`fetchBudget` を直接渡す cron 経路に同じ停止が残るため。

Closes #192
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
github-rag-mcp 3d46f8e Aug 02 2026, 07:13 AM

@liplus-lin-lay liplus-lin-lay self-assigned this Aug 2, 2026

@liplus-lin-lay liplus-lin-lay left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review (auto mode, parent agent)

受け入れ条件

  • 拡張子が既知でない page に対し limit=1 で繰り返し呼んだとき walk が前進する — 満たす。追加テスト 1 本目が 3 pass 連続で cursor p1p2p3 を固定している
  • visited >= 1 以降は予算超過が起きない — 満たす。3 本目が fetchBudget: 2 で 2 attempt 打ち切り・failed: 0・cursor 据え置きを固定
  • テストで固定されている — 満たす

制約

  • #185 の判断(観測していない失敗を計上しない)の維持 — 維持されている。exemption は visited === 0 に限定され、その page は候補リストを試し切ってから 404 と判定するので、計上される failure は実際に観測したものだけという性質は変わらない。2 本目のテストがこの性質を負の対照として固定している
  • limit 上限 40 は不変src/index.ts に変更なし

実装の確認

visited === 0 が成立するのは pass の初回 iteration に限られる(後続の continue 経路はすべて visited++ の後にあり、break 経路は visited === 0 では発火しない)。したがって exemption は pass あたり厳密に 1 回で、超過は最大 候補数 - 1 = 3 subrequest。

WikiPollSummary.fetches の「予算を超えない」という不変条件が緩んだ点は、doc comment・docs/0-requirementsdocs/installation の運用ノートの 3 箇所に反映済み。docs は実装と同一 PR。

scope からの逸脱

なし。

補足

追加 3 本のうち 3 本目は修正前後どちらでも通る。これは「先頭 page 以外の挙動を変えていない」ことを固定する不変条件側のテストで、意図どおり。回帰を捕まえるのは 1・2 本目。実装者から self-review の材料として明示的に申告があった点で、隠れた弱点ではない。

次のステップ

auto mode につき human gate なし。self-review pass → merge。

@liplus-lin-lay
liplus-lin-lay merged commit 9ae8241 into main Aug 2, 2026
3 checks passed
@liplus-lin-lay
liplus-lin-lay deleted the 192-bugwiki-a-limit-smaller-than-one-pages-probe-count-stalls-the-walk-cursor branch August 2, 2026 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(wiki): a limit smaller than one page's probe count stalls the walk cursor

1 participant