docs(worker): record the SemaphoreSlim/STA dispatch invariant + single-waiter contract; harden fake
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ZB.MOM.WW.MxGateway.Contracts.Proto;
|
||||
@@ -389,20 +390,32 @@ public sealed class MxAccessEventQueueTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the timeout still bounds an unsignalled wait: the fallback survives as a ceiling
|
||||
/// on how long a caller may sleep, so a state change reached by some future path that does
|
||||
/// not signal is still observed on the next pass rather than never.
|
||||
/// Verifies the timeout still bounds an unsignalled wait, from both sides: the wait ends
|
||||
/// without a signal (the fallback survives as a ceiling, so a state change reached by some
|
||||
/// future path that does not signal is still observed on the next pass rather than never)
|
||||
/// and it does not end early (the wait really is the timeout, not an already-armed permit
|
||||
/// completing it instantly). A longer-than-production timeout is used so the lower bound
|
||||
/// carries a wide margin over timer resolution.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task WaitForEventsAsync_WithNoSignal_CompletesAtTheFallbackTimeout()
|
||||
{
|
||||
MxAccessEventQueue queue = new(capacity: 4);
|
||||
TimeSpan fallback = TimeSpan.FromMilliseconds(200);
|
||||
Stopwatch elapsed = Stopwatch.StartNew();
|
||||
|
||||
Task wait = queue.WaitForEventsAsync(TimeSpan.FromMilliseconds(25), CancellationToken.None);
|
||||
Task wait = queue.WaitForEventsAsync(fallback, CancellationToken.None);
|
||||
|
||||
Assert.Same(wait, await Task.WhenAny(wait, Task.Delay(WakePatience)));
|
||||
await wait;
|
||||
elapsed.Stop();
|
||||
|
||||
// Half the timeout: far enough below it to be immune to timer resolution, far enough above
|
||||
// zero to fail an implementation that returned a completed task instead of waiting.
|
||||
Assert.True(
|
||||
elapsed.Elapsed >= TimeSpan.FromMilliseconds(100),
|
||||
$"Unsignalled wait returned after {elapsed.ElapsedMilliseconds} ms, well inside its {fallback.TotalMilliseconds} ms fallback.");
|
||||
}
|
||||
|
||||
/// <summary>Verifies a cancelled wait unwinds instead of hanging until the fallback expires.</summary>
|
||||
|
||||
Reference in New Issue
Block a user