When events arrive in a burst, each NotifyLiveSubscriptionMessage call
was scanning the entire buffer to push events to clients. Client acks
are queued behind the event flood in the same FIFO queue, so clients
appear full and every scan is fruitless. With N events, this results
in O(N²) total work.
Instead of pushing synchronously on event arrival, we now schedule a
push message on the PS queue. This lets events accumulate in the
buffer cheaply, gives acks a chance to interleave, and batches the
buffer scan.
All PushToClients call sites use the deferred path for consistency,
since the buffer scan cost applies equally to acks, nacks, timeouts,
and client changes.
For pinned strategies when events arrive in a burst, each NotifyLiveSubscriptionMessage call was scanning the entire buffer to push events to clients. Client acks are queued behind the event flood in the same FIFO queue, so clients appear full and every scan is fruitless. With N events, this results in O(N²) total work.
Instead of pushing synchronously on event arrival, we now schedule a push message on the PS queue. This lets events accumulate in the buffer cheaply, gives acks a chance to interleave, and batches the buffer scan.
All PushToClients call sites use the deferred path for consistency, since the buffer scan cost applies equally to acks, nacks, timeouts, and client changes.