Repository navigation
Give RemoteHost tests thread-pool headroom above xunit's synchronous slots - #21613
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 21613Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 21613" |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
This diagnostic-only revision still needs Windows CI trace analysis to establish the stall’s cause, with the intended fix and regression test pending.
No open issues 🎉
What changed in this PR
This work-in-progress PR adds temporary diagnostics to investigate the Windows-only stall in RemoteHost initialization tracked by #21612. It does not yet implement the fix or add regression coverage.
Changes:
- Records initialization milestones and capability-discovery logs.
- Samples thread-pool activity and garbage-collection counters every 250 ms on a background thread.
- Flushes diagnostics to test output whether the initialization wait succeeds or throws.
| File | Description |
|---|---|
tests/Aspire.Hosting.RemoteHost.Tests/IntegrationHostLauncherTests.cs |
Instruments the affected test with phase logging, runtime sampling, and diagnostic output helpers. |
Review effort: Balanced
…slots (#21612) xunit v3's conservative scheduler pins the thread-pool minimum to the number of synchronous tests it runs concurrently. On 4-core Windows runners long CPU-bound sync tests occupied every worker at that floor and JSON-RPC continuations for capability discovery queued for 4-11s, timing out InitializeHostsAsync_WaitsForEveryRegistrationBeforeDiscovery. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ce75c86 to
403a16f
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
The test can dispose synchronization events before queued callbacks finish, risking an unhandled ObjectDisposedException that terminates the test process; callbacks must be drained before disposal.
1 open issue
Review effort: Balanced
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sébastien Ros (sebastienros)
left a comment
There was a problem hiding this comment.
LGTM. Discovery cleanup now waits for any timed-out operation before subsequent tests run.
Tests selector1 / 100 PR test projects · 0 PR jobs, from 2 changed files. Selected PR test projects (1 / 100)
Selected PR jobs (0)none How these were chosen — grouped by what changed🧪 🧪 Job reasonsnone Selection computed for commit |
|
✅ No documentation update needed. docs_optional → test_only. No signals triggered (signal_count 0). Both changed files match |

Description
Fixes #21612. Part of #21600.
IntegrationHostLauncherTests.InitializeHostsAsync_WaitsForEveryRegistrationBeforeDiscoveryintermittently fails on Windows withSystem.TimeoutExceptionat the 10sinitialization.WaitAsync(line 124).7-day frequency (main
ci.yml, attempt 1):The failing jobs were 122368418345, 122578764141 and 122961611924. Passing Windows runs still take 4.2–6.8s, compared with 0.06s on Linux and 0.1s locally, so the test is close to timing out even when it passes.
Root cause: thread-pool starvation
A temporary diagnostics commit on this PR, now dropped, captured thread-pool state on Windows CI in run 41238866885:
getCapabilitiesdiscoveryExportApi_*andScanAssembly_*testsThe chain of events:
ExecutionScheduler._Conservative) sets the thread-pool minimum toMath.Max(4, maxParallelThreads). That is exactly the number of synchronous tests it can run at once.Fix
A
[ModuleInitializer]in the RemoteHost test assembly (TestThreadPoolHeadroom) raises the minimum worker threads to2 * max(4, ProcessorCount). This leaves headroom above xunit's synchronous slots for async continuations.Regression test
IntegrationHostDiscoveryThreadPoolTests.InitializeHostsAsync_CompletesWhileSynchronousTestsOccupyEverySchedulerSlotruns in aDisableParallelizationcollection:SynchronousTestSlotsworkers with blocking work items.InitializeHostsAsyncdiscovery over two JSON-RPC test connections.Results:
Capability discovery could not complete while 4 synchronous tests occupied the thread pool (minimum workers: 4, slots occupied: False, discovered: False).IntegrationHostLauncherTests,ApiReferenceExportTestsandAtsCapabilityScannerTestsclasses (92 tests, 0 failures each run).CI evidence (windows-latest Hosting.RemoteHost, from TRX)
WaitsForEveryRegistrationBeforeDiscoveryOn main, Windows runs of
WaitsForEveryRegistrationBeforeDiscoverytook 4.2–11.7s, and the failing runs timed out at 10s. The full CI run passed 43/43 jobs on 433cda8.Checklist
🤖 Posted by AspireAgent (AI Agent)