fix(install): fail fast when MCP parent respawns tempyr.exe#39
Conversation
The lock-recovery path silently retried cargo install up to four times
when a parent process (another Claude Code session, an IDE, etc.)
respawned `tempyr --mcp` children faster than we could kill them. Each
attempt also stalled up to 60s on `Wait-Process -Timeout 15` per PID
when Stop-Process silently failed, making the script feel hung.
- Cut per-PID Wait-Process timeout from 15s to 2s. Force-kill is
synchronous; the long wait only ever stalled when the kill failed.
- `Stop-TargetProcesses` now returns `{Cleared, Respawned}`. If the
post-kill PIDs differ from what we killed, a parent is respawning
them and `Invoke-CargoInstallWithLockRecovery` throws with a clear
message telling the user to close other Claude Code / IDE sessions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
Changes
Sequence Diagram(s)sequenceDiagram
participant Installer as Installer Script
participant StopFn as Stop-TargetProcesses
participant OS as Operating System / Processes
participant LockChk as Test-FileLocked
participant Cargo as cargo installer
Installer->>StopFn: request stop of Tempyr PIDs
StopFn->>OS: force-stop targeted processes
OS-->>StopFn: remaining matching processes (new PIDs?)
StopFn->>StopFn: compare original vs remaining PIDs -> set Respawned
StopFn->>LockChk: check file lock state
LockChk-->>StopFn: IsUnlocked (true/false)
StopFn-->>Installer: return {PidsCleared, IsUnlocked, Respawned}
alt Respawned = true
Installer->>Installer: throw instructive error (abort)
else IsUnlocked = true
Installer->>Cargo: attempt cargo install (retry)
else
Installer->>Installer: follow delay-and-retry loop (no immediate retry)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Review rate limit: 3/5 reviews remaining, refill in 13 minutes and 57 seconds. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@install.ps1`:
- Around line 89-105: Stop-TargetProcesses currently returns Cleared = $true
when matching tempyr PIDs disappear even if the file remains locked; update
Stop-TargetProcesses to re-check the actual file lock (call Test-FileLocked
-BinaryPath $BinaryPath or equivalent) before returning Cleared = $true and only
set Cleared = $true when Test-FileLocked reports unlocked; alternatively, if you
prefer a rename approach, change the return field (e.g., PidsCleared) to
indicate only PID removal and add a separate IsUnlocked boolean driven by
Test-FileLocked so callers (the retry logic at the cargo re-run site) gate fast
retries on IsUnlocked rather than the PID-only flag.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Stop-TargetProcesses previously signaled Cleared=true whenever matching tempyr.exe PIDs were gone, even if the binary stayed locked by something else (AV scan mid-flight, Explorer preview, stale kernel handle). The caller would then fast-retry cargo without the file-in-use cause having actually cleared. Split the return into PidsCleared (kill worked) and IsUnlocked (Test-FileLocked confirms the binary is now writable). Caller's fast-retry branch now gates on IsUnlocked; PIDs-cleared-but-still-locked falls through to the delay-and-retry path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
install.ps1's lock-recovery path could feel hung for several minutes when a parent process (another Claude Code session, an IDE with tempyr registered as an MCP server, etc.) respawnedtempyr --mcpchildren faster than we could kill them. Two fixes:Wait-Process -Timeout 15to-Timeout 2. Force-kill is synchronous; the long timeout only stalled whenStop-Processsilently failed (e.g. access denied), turning four PIDs into 60s of silence per attempt.Stop-TargetProcessesnow returns{Cleared, Respawned}. If post-kill PIDs differ from the ones we killed, a parent is winning the race and retrying cargo will too. We now throw immediately with a clear message: close those clients and re-run.Test plan
.\install.ps1with no other tempyr clients running → installs cleanly in one pass..\install.ps1while another Claude Code session has tempyr MCP wired up → fails fast with the "close those clients" message instead of grinding through four cargo retries..\install.ps1against a binary locked by a non-respawning process → kills it on first attempt and proceeds.🤖 Generated with Claude Code
Summary by CodeRabbit