feat: 修正失敗時のリトライを追加#10
Conversation
There was a problem hiding this comment.
Pull request overview
Worker の dev server 起動失敗時に、同一 Pod 内で Claude に自己修復させてリトライすることで、失敗率低減と再実行コスト削減を狙う PR です(LangGraph 側の Job リトライではなく Worker 内リトライを採用)。
Changes:
- dev server 起動〜スクリーンショット取得をリトライするループを追加(最大2回リトライ)
- 失敗時に dev server プロセスを停止する
kill_dev_servers()と、Claude に修正させるfix_with_claude()を追加 .dockerignoreを新規追加し、Docker build コンテキストを抑制
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| docker/worker-implement.py | スクリーンショット取得の検証強化と、失敗時の自己修復リトライ導入 |
| .dockerignore | node_modules 等を除外してビルドコンテキストを削減 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| except Exception as e: | ||
| last_error = str(e) | ||
| if attempt < max_retries: | ||
| emit_log( | ||
| "implementing", | ||
| f"Dev server launch failed (attempt {attempt + 1}/{max_retries + 1}), attempting fix...", | ||
| detail=last_error, | ||
| ) | ||
| await kill_dev_servers(repo_dir) | ||
| await fix_with_claude(repo_dir, last_error) |
There was a problem hiding this comment.
On failure you pass str(e) into fix_with_claude(), but the most common exception here is the synthetic “Screenshot was not created...” error, which doesn’t include the actual dev server/stdout/stderr that Claude needs to fix the root cause. Consider capturing and surfacing the relevant launch/screenshot command outputs (or writing them to a file and including that content) so the retry/fix prompt contains actionable error details.
| async def kill_dev_servers(repo_dir: str) -> None: | ||
| """Kill any lingering dev server processes (node, vite, next, etc.).""" | ||
| for pattern in ["node", "vite", "next"]: | ||
| subprocess.run( | ||
| ["pkill", "-f", pattern], | ||
| capture_output=True, | ||
| ) |
There was a problem hiding this comment.
kill_dev_servers() relies on calling pkill, but the current worker image build (docker/worker.Dockerfile) does not install procps, so pkill is likely missing and this will raise FileNotFoundError, breaking the retry flow. Either install the needed OS package in the worker image or handle the absence of pkill (e.g., fallback to another mechanism) so retries don’t fail immediately.
| async def kill_dev_servers(repo_dir: str) -> None: | ||
| """Kill any lingering dev server processes (node, vite, next, etc.).""" | ||
| for pattern in ["node", "vite", "next"]: | ||
| subprocess.run( | ||
| ["pkill", "-f", pattern], | ||
| capture_output=True, | ||
| ) |
There was a problem hiding this comment.
kill_dev_servers(repo_dir) doesn’t use repo_dir and runs pkill -f on very broad patterns (node, vite, next). That can terminate unrelated processes in the container (and makes the parameter misleading). Prefer scoping the kill to processes launched for this repo (e.g., match repo_dir in the command line, or better: capture and store the dev server PID when starting it and kill that PID/process group).
自己修復アプローチ
今回 → Worker 内 Claude 修正を採用
理由
修正精度が圧倒的に高いためWorker 内 Claude 修正を採用する。dev server 起動失敗の原因は実装ミス(ポート指定、依存関係、ビルドエラー等)が大半で、Claude が「自分の実装コンテキスト」を保持したまま修正できる ので精度がいいはずと判断した。ただ、コンテナを起動&並列処理が10を超えてくると、jobを再度渡すのがいいかもしれない
一時的な緩和策
WORKER_DEADLINE_SECONDSを 900 → 1200 に引き上げkillで 前回の dev server プロセスを確実に停止