Repository navigation
Accept natural ps leader exit racing a failed Windows taskkill (Fixes #20869) - #21595
Conversation
When a short-lived CLI child (e.g. one-shot aspire ps) exits on its own while forced taskkill is running, Windows denies termination (taskkill exit 255) and libuv's kill() returns false because the process already exited. The fallback path threw immediately, and AppHostPsPoller permanently retained that failure, so no replacement ps follower started. Wait for close within the remaining deadline and accept a clean exit 0 (forced termination yields exit 1); otherwise preserve the taskkill error. Fixes microsoft#20869 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 21595Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 21595" |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are recorded for the Windows process-termination race fix.
No open issues 🎉
What changed in this PR
Fixes a Windows process-termination race in the VS Code extension that could prevent a replacement AppHost watcher from starting after an aspire ps command exits naturally.
Changes:
- Waits within the remaining deadline for the CLI leader to close when fallback termination returns false.
- Accepts a clean, signal-free exit while preserving the original taskkill error for other outcomes.
- Adds regression tests for natural and forced exits, including listener and timer cleanup.
| File | Description |
|---|---|
extension/src/utils/process/cliProcess.ts |
Handles natural CLI exits racing with failed Windows taskkill. |
extension/src/test/cliSpawn.test.ts |
Tests acceptance of clean exits and preservation of termination errors. |
Review effort: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Ella Hathaway (ellahathaway)
left a comment
There was a problem hiding this comment.
I reviewed the Windows termination fallback, AppHost poller cleanup and restart flow, and regression coverage. I found no blocking correctness issues or nonblocking design concerns.
2593521
into
microsoft:main
Description
Fixes the intermittent VS Code extension E2E (Windows, apphost-tree) failure
owns at most one ps follower…. The test reportsTimed out after 30000ms waiting for 1 owned ps follower(s)and the state errorFailed to stop the previous AppHost watcher: Error: taskkill for aspire ps exited with code 255 while PID N remained live.Denominator (ci.yml, 2026-10-29 13:00Z → 10-31 13:23Z, 388 runs)
main(run 40905807668, job 123572993753).Root cause (from the artifact
extension-e2e-diagnostics-win-x64-apphost-tree-attempt1of run 40905807668)aspire ps --format json(PID 7120). The poller stops at .746 and forcestaskkill /pid 7120 /t /f.Exit code: 0at 46.800 andHosting stoppedat 46.809. The process finished on its own while taskkill was running.child.kill('SIGKILL')returnsfalse.killLeaderAsFallbackthen threw the taskkill error 3ms later.AppHostPsPoller._terminatePsProcesskeeps that failure permanently, so a replacement follower never starts and the test times out.Fix
In
killLeaderAsFallback, when the fallbackkill()returns false, wait forclosewithin the remaining deadline.There are no sleeps or retries, and no assertions were relaxed.
Regression tests (
extension/src/test/cliSpawn.test.ts)accepts a failed taskkill when the leader already finished on its own before its exit was observed: fails before the fix with the exact CI error (taskkill for test Aspire CLI exited with code 255 while PID 5100 remained live) and passes after.preserves a failed taskkill when the leader was terminated rather than finishing on its own: exit code 1 still rejects.vscodemodule stub, because the sandbox can't download VS Code. They all pass. CI runs the full extension unit and E2E suites on Windows.CI evidence (head 6c3bb2e, run 41211446478)
Run VS Code extension unit tests (Windows)passed, including the new regression tests.VS Code extension E2E (Windows, apphost-tree), the flaky shard, passed on the first attempt.VS Code extension E2E (Windows, edge-cases)failed with runner loss: "The hosted runner lost communication with the server", with no log blob (the known Windows CI runners lose communication during test steps since the windows-2025-vs2026 20261007 image (not test hangs) #21570 signature). The repo's automatic retry ran attempt 2, which passed. No other job was rerun.Checklist
🤖 Posted by AspireAgent (AI Agent)