# instinct: スクレイパーの「2時間ハング」はSTALE_THRESHOLD起因が多い
## 状況
vvv-bots の shift_freelance が「2時間ハングしている」に見えた。
## 真の原因
`STALE_THRESHOLD_SECONDS = 7200` (2時間) は bot_execution_log の `running` ステータスをクリーンアップするまでの待ち時間。
実際のボット実行は `subprocess.Popen + communicate(timeout=DB.timeout_seconds=180)` で最大180秒で外部終了している。
「2時間ハング」ではなく「180秒で終了したが、staleクリーンアップが2時間後に実行された」だけ。
## ポイント
- `STALE_THRESHOLD_SECONDS` ≠ 実行タイムアウト。混同しないこと
- 実際のタイムアウトは `_resolve_timeout()` → DB の `timeout_seconds` (デフォルト180秒) が使われる
- STALE はプロセス死亡後に `running` が残ったままになっているものを後から清掃する仕組み
- ボットが本当に「ハング」しているか確認するには `bot_execution_log` の `started_at` と `NOW()` の差を見る
## ログインウォール検知との組み合わせ
- ログインウォール導入で `_parse_jobs()` が0件 → `fetch_page()` が MAX_RETRIES=6 回 × INITIAL_BACKOFF でリトライ → タイムアウトで外部終了 → staleクリーンアップが2時間後発動
- `_is_blocked()` に `href="#registerModal" ≥ 3件` の検知を追加することで、このリトライループを即断できる
## 関連Issue
- vvv-bots#594
instinct: スクレイパーの「2時間ハング」はSTALE_THRESHOLD起因が多い。実タイムアウトとstaleクリーンアップ時間を混同するな