Repository navigation
De-flake HubsDocTests dynamic merge: async expectation with an explicit 10s timeout - #8664
Merged
Aaronontheweb merged 1 commit intoSep 29, 2026
Conversation
…it 10s timeout The test used the sync ExpectMsgAllOf with the 3s default. On a stalled Windows agent the first element reached the TestActor right at the deadline and the expectation threw OperationCanceledException. MergeHub always delivers both elements, so wait on them asynchronously with a 10s budget instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
DocsExamples.Streams.HubsDocTests.Hubs_must_demonstrate_creating_a_dynamic_mergefailed on the Windows agent (build 132091, net10.0, 8 s) withOperationCanceledExceptionthrown fromExpectMsgAllOf. That PR only touched extension loading, so the failure was unrelated to it.Root cause
The test called the sync
ExpectMsgAllOf(params T[]), which cancels a token after the 3 s default. The stack shows the throw atcancellationToken.ThrowIfCancellationRequested()inInternalReceiveNAsync: the first element was received, but only at the deadline. So the stream delivered late, not never. Two details point to a stalled agent: the test took 8 s in total when the wait was 3 s, and it normally runs in about 30 ms.MergeHub has no race here. Producers that start before the hub stage enqueue their
Register/Element/Deregisterevents in FIFO order, and the hub drains them on its first pull. Both elements always arrive.ExpectMsgAllOfdoes not depend on order. Pekko'sHubsDocSpecis the same code with the same default timeout.Fix
async Taskand useawait ExpectMsgAllOfAsync(TimeSpan.FromSeconds(10), ...). It waits on the real signal (both elements reaching the TestActor), no longer blocks a pool thread (half the pool minimum on a 2-vCPU agent), and has an explicit budget that costs nothing when the test passes.#region merge-hubexample code is unchanged.Verification
Thread.Sleepin the test's consumer delegate made the old test fail every time withOperationCanceledException. At 2985 ms, 2 of 4 runs matched the CI stack exactly (throw atTestKitBase_Receive.cs:825).HubsDocTestsclass: 10/10 passes, plus 10/10 withDOTNET_PROCESSOR_COUNT=2.