fix(WRK-22,WRK-24,WRK-25,WRK-27,IPC-26): worker write-seam hardening
WRK-22/IPC-26: tombstone a WriteAsync/WriteBatchAsync cancelled while waiting for the write lock (PendingFrame.Claimed under _gate; DequeueNext skips cancelled, claims the frame it returns) so a cancelled write never reaches the wire unless already claimed mid-write (documented residual). WRK-25: add WriteBatchAsync; RunEventDrainLoopAsync submits the drained event batch through it, so a burst of N events costs one flush not N. IPC-30 oversized-event structured fault preserved via FindOversizedEvent. WRK-24: reject a below-1024 negotiated frame maximum at the handshake (MinNegotiableFrameBytes, matching GatewayOptionsValidator floor). WRK-27: alarm poll advertises StaCallInProgress on the heartbeat snapshot so the watchdog suppresses to the ceiling, not the grace. Docs (WorkerFrameProtocol.md, MxAccessWorkerInstanceDesign.md) and the 2026-07-12 remediation registers/change-log updated in the same commit.
This commit is contained in:
@@ -747,6 +747,23 @@ heartbeat fields until dedicated thresholds own those warnings. The worker
|
||||
reports stale STA activity, but the gateway owns the final kill decision
|
||||
through its existing heartbeat and worker lifecycle policy.
|
||||
|
||||
The alarm poll runs outside the command dispatcher — `RunAlarmPollLoopAsync`
|
||||
invokes `PollOnce` directly on the STA rather than through
|
||||
`StaCommandDispatcher`, so it does not inflate `PendingCommandCount` or perturb
|
||||
dispatch ordering for real gateway commands. Because it is not a dispatched
|
||||
command it has no `CurrentCommandCorrelationId`, so a healthy-but-slow poll (a
|
||||
large `GetXmlCurrentAlarms2` against a busy provider) blocking the STA past
|
||||
`HeartbeatGrace` would otherwise fault a healthy session at 15 s while a
|
||||
dispatched command gets the 75 s ceiling. To close that asymmetry (WRK-27) the
|
||||
poll advertises itself on the heartbeat snapshot's `StaCallInProgress` flag —
|
||||
set on the STA thread for exactly the span of the COM call — and the watchdog
|
||||
suppression honors that flag alongside `CurrentCommandCorrelationId`. The poll
|
||||
therefore receives the same grace-to-ceiling treatment as a dispatched command:
|
||||
suppressed up to `HeartbeatStuckCeiling`, faulted past it (a poll that blocks
|
||||
the STA more than 75 s without pumping *should* fault — that is the ceiling's
|
||||
contract). The flag is named generically so any future non-dispatcher STA work
|
||||
reuses it.
|
||||
|
||||
The in-flight-command suppression itself is bounded by
|
||||
`WorkerPipeSessionOptions.HeartbeatStuckCeiling` (default 75 seconds = 5 ×
|
||||
`HeartbeatGrace`). The motivating case for the suppression is a legitimately
|
||||
|
||||
Reference in New Issue
Block a user