perf(worker): signal-driven event drain — removes the 25 ms latency floor and idle wakeups
This commit is contained in:
@@ -15,6 +15,11 @@ namespace ZB.MOM.WW.MxGateway.Worker.Ipc;
|
||||
|
||||
public sealed class WorkerPipeSession
|
||||
{
|
||||
// Fallback ceiling for the event drain loop's wait — not a poll period. MxAccessEventQueue
|
||||
// signals on enqueue (and on a recorded fault), so the loop wakes as soon as there is something
|
||||
// to ship instead of paying up to this interval of latency on every burst from idle, and an
|
||||
// idle worker parks instead of waking 40x/s. The interval survives only as the bound on how
|
||||
// long the loop may sleep unsignalled, which keeps its DrainFault() poll on a known cadence.
|
||||
private static readonly TimeSpan EventDrainInterval = TimeSpan.FromMilliseconds(25);
|
||||
private static readonly TimeSpan BackgroundTaskStopTimeout = TimeSpan.FromSeconds(1);
|
||||
private const uint EventDrainBatchSize = 128;
|
||||
@@ -367,7 +372,15 @@ public sealed class WorkerPipeSession
|
||||
IReadOnlyList<WorkerEvent> events = runtimeSession.DrainEvents(EventDrainBatchSize);
|
||||
if (events.Count == 0)
|
||||
{
|
||||
await Task.Delay(EventDrainInterval, cancellationToken).ConfigureAwait(false);
|
||||
// Wait on the queue's wake signal rather than sleeping a fixed tick: an event
|
||||
// enqueued by the STA completes this immediately, so the first event of a burst is
|
||||
// framed at signal latency instead of waiting out EventDrainInterval, and a session
|
||||
// with no traffic stops waking at all. The wait's outcome is intentionally ignored —
|
||||
// whether a signal or the fallback ended it, the next pass re-checks DrainFault()
|
||||
// and re-drains, which is also why one coalesced wake for many enqueues is safe.
|
||||
await runtimeSession
|
||||
.WaitForEventsAsync(EventDrainInterval, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user