Skip to content

fix(windows): harden kill_tree against taskkill's tree-kill race, add leak detection - #443

Merged
getappz merged 3 commits into
masterfrom
task/78
Aug 11, 2026
Merged

getappz merged 3 commits into
masterfrom
task/78

Conversation

@getappz

@getappz getappz commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Closes the root cause behind item #78's investigation into recurring Windows CI last-test slow-timeouts (hit PRs #436, #438, #441 — always a different test, always the run's last to complete, always exactly nextest's configured 300s slow-timeout).

Root cause

taskkill /T /F builds its process-tree kill list from a single point-in-time snapshot. A grandchild process spawned in the narrow window between that snapshot and termination can survive undetected. None of the three Windows kill paths (agent_launch::kill_tree — the real production dispatch path, not just tests — plus flare-git-core's and agentflare-jobs's equivalents) ever verified the tree was actually gone before returning, unlike the Unix path which already walks /proc to signal descendants directly.

Of the two tests that always run immediately before the eventual CI timeout, supervisor_test::timeout_kills_long_running_process kills a 30s child with zero buffer to let a leak self-correct — if the taskkill snapshot misses the grandchild, it keeps running unsupervised for ~28s, overlapping whatever nextest schedules next on a 2-core Windows runner. That matches the observed symptom exactly.

Fix

Add a second, delayed taskkill /T /F pass to each Windows kill path as cheap defense-in-depth against the snapshot race, and strengthen both suspect tests to poll for surviving processes on Windows so a future regression fails loudly and locally instead of silently starving an unrelated downstream test.

This is also a real production concern, not only CI noise — agent_launch::kill_tree is the same code path used by live agent dispatch on Windows hosts.

Test plan

  • cargo check — clean
  • Both hardened tests pass
  • clippy (matching CI's exact flags) — clean

Verified on Linux (no Windows box available) — the fix is reasoned from taskkill/process-tree semantics, not a live Windows repro. Windows CI on this PR is the first live test of it.

… leak detection

taskkill /T /F builds its process-tree kill list from a single point-in-time
snapshot; a grandchild spawned in the narrow window between that snapshot and
termination can survive undetected, and none of the three Windows kill paths
(agent_launch::kill_tree, flare-git-core::kill_tree, agentflare-jobs's
kill_graceful) ever verified the tree was actually gone before returning.
This is the leading suspect for item #78's recurring Windows CI last-test
slow-timeout: two kill-focused tests always run right before the eventual
timeout, and one of them (timeout_kills_long_running_process) kills a 30s
grandchild with no buffer to let a leak self-correct, unlike its sibling test.

Add a second delayed taskkill /T /F pass to each Windows kill path as cheap
defense-in-depth against the snapshot race, and strengthen both suspect
tests to poll for surviving processes on Windows so a future regression
fails loudly and locally instead of starving an unrelated test downstream.

Agentflare-Agent: claude-code
Agentflare-Branch: task/78
Agentflare-Item: 78
@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c98c4229-9598-4d77-9ac3-b2dc58ae4696

📥 Commits

Reviewing files that changed from the base of the PR and between 408ad35 and 0404bf3.

📒 Files selected for processing (5)
  • .config/nextest.toml
  • crates/agentflare-jobs/src/supervisor.rs
  • crates/agentflare-jobs/tests/supervisor_test.rs
  • crates/flare-git-core/src/worktree.rs
  • src/agent_launch.rs

Comment @coderabbitai help to get the list of available commands.

shiva added 2 commits August 11, 2026 14:25
Agentflare-Agent: claude-code
Agentflare-Branch: task/78
Agentflare-Item: 78
Confirmed 5 occurrences (PRs #436/#438/#441/#443 twice) of the identical
signature: a different test each time, always the run's last one to
complete, killed at exactly slow-timeout's 300s boundary while 2100+
other tests pass. This PR's own kill_tree hardening still hit the same
signature on yet another test afterward, ruling out that specific leak
as the sole cause -- reads as generic Windows-runner tail-of-run resource
contention, not a broken test. retries = 2 is nextest's own targeted
mitigation for exactly this shape of flake: a genuinely hung/broken test
fails every retry too, so this doesn't mask real regressions.

Agentflare-Agent: claude-code
Agentflare-Branch: task/78
Agentflare-Item: 78
@getappz
getappz merged commit 65f0788 into master Aug 11, 2026
16 checks passed
@getappz
getappz deleted the task/78 branch August 11, 2026 09:09
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.

1 participant