fix: serialize MTP server-mode concurrent sessions to prevent stochastic 0-result runs#6002
fix: serialize MTP server-mode concurrent sessions to prevent stochastic 0-result runs#6002Copilot wants to merge 3 commits into
Conversation
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| ErrorProne | 1 high |
🟢 Metrics 4 complexity
Metric Results Complexity 4
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
…tic 0-result runs When multiple concurrent testing/runTests RPCs arrive at the same TUnit process, they race on shared static state (GlobalContext.Current, AppDomain exception handlers, Trace.Listeners). This causes stochastic 0-result sessions under concurrency. Changes: - Add SemaphoreSlim(1,1) in TUnitTestFramework.ExecuteRequestAsync to serialize concurrent requests - Make TUnitInitializer.Initialize idempotent with static flags to prevent repeated global handler/listener registration - Add multi-session RPC tests validating sequential and concurrent runTests RPCs produce consistent results
|
@copilot this is a band aid - we should correctly scope static state to either instance level or async local. Concurrent runs is a valid pattern. |
…sions Replace the shared static field with AsyncLocal<GlobalContext?> (matching TestSessionContext, BeforeTestDiscoveryContext, TestDiscoveryContext). A process-level DefaultInstance serves source-gen module initializers that run before any session sets the AsyncLocal value. This allows concurrent testing/runTests RPCs to each have their own GlobalContext without overwriting each other, enabling true concurrent multi-session support in MTP server mode. Removes the SemaphoreSlim serialization approach (band-aid) in favor of properly scoped state as requested.
Agreed — removed the |
Multiple concurrent
testing/runTestsRPCs to one long-lived TUnit process race on shared static state (GlobalContext.Current,AppDomain.UnhandledExceptionhandlers,Trace.Listeners), producing stochastic 0-result sessions. Sequential execution is deterministic and correct; concurrency introduces variance.Changes
Serialize
ExecuteRequestAsync— addedSemaphoreSlim(1, 1)inTUnitTestFrameworkso concurrent RPCs queue and execute sequentially. The perf win from MTP server mode is avoiding process startup overhead, not intra-process parallelism.Make
TUnitInitializer.Initializeidempotent — static volatile flags prevent repeatedAppDomain.UnhandledExceptionhandler registration andTrace.Listenersinsertion across sessions.Add multi-session RPC tests — validates both sequential (3×) and concurrent (3× parallel)
runTestsRPCs against the same server produce consistent, complete results.