33ba612ddd
WRK-21 — DrainEvents was bounded by event count only, so a byte-heavy queue (large string/array MxValues) built a reply above the negotiated frame maximum: the writer rejected the frame, the exception unwound the session, and the events already dequeued were destroyed. The drain is now byte-budgeted inside the queue lock, so an event is dequeued only once it is known to fit and one that does not stays at the head. Truncation is reported through the reply's existing DiagnosticMessage (no contract change); callers drain until an empty reply. Both reply-write seams — the control-command path and ProcessCommandAsync — now catch MessageTooLarge and answer the correlation with an InvalidRequest reply instead of unwinding or faulting the session. Satisfies IPC-23 R1-R3. WRK-28 — the 10,000 drain ceiling moves to GatewayContractInfo .MaxDrainEventsPerCommand, referenced by both the gateway request validator and the worker clamp, replacing a comment-only sync contract. C# const only; no .proto change. WRK-23 — WorkerFrameWriter now peek-stamps, validates, then commits the sequence counter immediately before the stream write, so a per-frame rejection leaves no phantom gap on the wire. IPC-30 — an oversized event frame stays session-fatal (it is undeliverable end to end and neither dropping nor synthesizing a replacement is allowed), but the death is structured: the event's identity and sizes are logged (never its value), a WorkerFault with category PROTOCOL_VIOLATION and command method EventDrain is written, then the session exits as before. Docs updated in the same change: MxAccessWorkerInstanceDesign.md (drain byte cap, truncation contract, oversized-head behavior, oversized-event policy, no control reply is session-fatal on size), WorkerFrameProtocol.md (reply pre-sizing, non-fatal reply-size rule, oversized-event policy, rejected frames do not consume sequence numbers), gateway.md (DrainEvents two-axis bound).
45 lines
2.4 KiB
C#
45 lines
2.4 KiB
C#
namespace ZB.MOM.WW.MxGateway.Contracts;
|
|
|
|
/// <summary>
|
|
/// Holds the protocol version constants shared by gateway components.
|
|
/// <see cref="GatewayProtocolVersion"/> is advertised to clients in
|
|
/// <c>OpenSessionReply</c>; <see cref="WorkerProtocolVersion"/> is used to
|
|
/// validate <c>WorkerEnvelope</c> protocol framing on the gateway↔worker pipe.
|
|
/// </summary>
|
|
public static class GatewayContractInfo
|
|
{
|
|
/// <summary>Protocol version advertised to clients in <c>OpenSessionReply</c>.</summary>
|
|
public const uint GatewayProtocolVersion = 3;
|
|
|
|
/// <summary>Protocol version used to validate <c>WorkerEnvelope</c> framing on the gateway-worker pipe.</summary>
|
|
public const uint WorkerProtocolVersion = 1;
|
|
|
|
/// <summary>Default backend name identifying the MXAccess worker process type.</summary>
|
|
public const string DefaultBackendName = "mxaccess-worker";
|
|
|
|
/// <summary>
|
|
/// Ceiling on how many events one <c>DrainEvents</c> command may move in a single reply.
|
|
/// Shared so the gateway's request-validation ceiling
|
|
/// (<c>MxAccessGrpcRequestValidator</c>, which rejects a larger <c>max_events</c> loudly at
|
|
/// the public boundary) and the worker's per-reply clamp
|
|
/// (<c>WorkerPipeSession.CreateDrainEventsReply</c>, the backstop that also interprets
|
|
/// <c>max_events = 0</c>) cannot drift apart. A count cap alone is necessary but not
|
|
/// sufficient: the worker additionally caps the reply by serialized bytes against the
|
|
/// negotiated frame maximum (WRK-21), so a reply may carry fewer events than this ceiling
|
|
/// and fewer than are queued. Callers drain iteratively until an empty reply.
|
|
/// This is a documented behavioral bound, not wire schema — it is deliberately a C#
|
|
/// constant and not a <c>.proto</c> field.
|
|
/// </summary>
|
|
public const uint MaxDrainEventsPerCommand = 10_000;
|
|
|
|
/// <summary>
|
|
/// Environment variable name that opts an xUnit suite into running live
|
|
/// MXAccess COM tests. Single source of truth shared by both
|
|
/// <c>ZB.MOM.WW.MxGateway.IntegrationTests.LiveMxAccessFactAttribute</c> and
|
|
/// <c>ZB.MOM.WW.MxGateway.Worker.Tests.TestSupport.LiveMxAccessFactAttribute</c>
|
|
/// so any future opt-in tweak does not silently leave one project
|
|
/// behind.
|
|
/// </summary>
|
|
public const string LiveMxAccessOptInVariableName = "MXGATEWAY_RUN_LIVE_MXACCESS_TESTS";
|
|
}
|