Skip to content

fix(scrape): sleep after failure too, back off longer on 429 - #192

Merged
128na merged 4 commits into
masterfrom
fix/scrape-rate-limit-backoff
Aug 20, 2026
Merged

fix(scrape): sleep after failure too, back off longer on 429#192
128na merged 4 commits into
masterfrom
fix/scrape-rate-limit-backoff

Conversation

@128na

@128na 128na commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Japan/Twitrans の HandlerSleep::for(1)->second() が成功パスにしかなく、失敗時は間隔なしで次の URL に進んでいた
  • wikiwiki.jp (Twitrans) で 429 を1件受けると、間隔ゼロの連続アクセスが続き、以降ほぼ全URLが429で連鎖失敗する状態だった(prod 8/19ログで286件失敗、8/20にユーザーが手動実行して再現)
  • wikiwiki.jp 側に公開されたレート制限値はない(robots.txt に Crawl-delay 指定なし、Cloudflare 経由で仕様非公開)ため、固定の「安全な間隔」を当てずっぽうで決めるのではなく、失敗時にも通常間隔(2秒)を必ず空け、429を受けた直後だけ長めのクールダウン(15秒)を挟む方式にした

Test plan

  • 新規 Twitrans/HandlerRateLimitTest で、成功時2秒・429直後15秒のスリープ順序を Sleep::fake()/assertSequence で検証
  • php artisan test --filter=Scrape 全14件パス
  • phpstan analyse エラーなし
  • pint --test パス

🤖 Generated with Claude Code

128na and others added 4 commits August 20, 2026 19:56
Japan/Twitrans の Handler は Sleep::for(1)->second() が try 節の成功
パスにしかなく、失敗時は間隔を空けずに次の URL へ進んでいた。
wikiwiki.jp (Twitrans) で一度 429 を受けると、間隔なしの連続アクセス
がそのまま続き、以降ほぼ全URLが 429 で失敗する連鎖が起きていた
(prod 8/19 ログで286件失敗)。

wikiwiki.jp 側に公開されたレート制限値は無い(robots.txt に
Crawl-delay 指定なし、Cloudflare 経由)ため、固定の「安全な間隔」を
決め打ちするのではなく、失敗時にも通常間隔(2秒)を必ず空け、429を
受けた直後だけ長めのクールダウン(15秒)を挟むようにした。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ローカルから php artisan app:scrape twitrans を実際に実行して検証した
ところ、2秒間隔+429後15秒クールダウンでは不十分だった。最初の4件は
バーストで通るが、それ以降は2秒間隔だとトークンが回復しきらず断続的
に429になり、15秒待っても直後の1件しか通らない(トークンバケット的な
挙動)。

Twitrans (wikiwiki.jp) のみ通常間隔を10秒、429後クールダウンを60秒に
引き上げる。Japan (japanese.simutrans.com) 側は429が一度も観測されて
いないため据え置き。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tests

コードレビュー指摘への対応。

- Japan/Twitrans の Handler に一字一句同じ sleepAfterFailure() が重複
  していたため、App\Actions\Scrape\SleepBetweenRequests に抽出。間隔/
  クールダウン秒数は各 Handler の定数のまま呼び出し時に渡す形にし、
  サイトごとの値の違い(Japan 2/15秒、Twitrans 10/60秒)は維持。
  あわせて定数名を IntervalSeconds → INTERVAL_SECONDS 等、同ディレク
  トリの既存定数(TOP_URL 等)に合わせた UPPER_SNAKE_CASE に統一。
- Scrape/Japan の HandlerFailureTest・HandlerIsolationTest が
  Sleep::fake() していなかったため、失敗時にも sleep するようになった
  前回PRの変更で実際に数秒待つようになっていた。Sleep::fake() を追加
  して解消(該当テストの実行時間 ~8秒 → ~0.1秒)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@128na
128na merged commit e1e9ee5 into master Aug 20, 2026
5 checks passed
@128na
128na deleted the fix/scrape-rate-limit-backoff branch August 20, 2026 11:33
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.

2 participants