Galaxy: wait on the gateway's stream-attached ack instead of the 1 s best-effort wait (mxaccessgw#227) #877

Closed
opened 2026-11-12 07:28:19 -05:00 by dohertj2 · 2 comments
Owner

mxaccessgw#227 (main afd504d5) adds an opt-in attach acknowledgement on StreamEvents, closing the race from #865. Not yet on the feed — blocked on an mxgw Client/Contracts release.

Changes needed:

  1. Bump to a client package that carries it.
  2. GatewayGalaxySubscriber.StreamEventsAsync → session.StreamEventsAsync(0, emitStreamAttached: true, ct).
  3. EventPump.RunAsync: handle ev.StreamAttached is not null next to the ReplayGap check — complete an 'attached' signal and continue (never dispatch it).
  4. AwaitCurrentEventStreamAsync: wait on that signal when OpenSessionReply.capabilities contains 'stream-events-attached-ack'; keep the 1 s wait only as the fallback for older gateways.
mxaccessgw#227 (main afd504d5) adds an opt-in attach acknowledgement on StreamEvents, closing the race from #865. Not yet on the feed — blocked on an mxgw Client/Contracts release. Changes needed: 1. Bump to a client package that carries it. 2. GatewayGalaxySubscriber.StreamEventsAsync → session.StreamEventsAsync(0, emitStreamAttached: true, ct). 3. EventPump.RunAsync: handle ev.StreamAttached is not null next to the ReplayGap check — complete an 'attached' signal and continue (never dispatch it). 4. AwaitCurrentEventStreamAsync: wait on that signal when OpenSessionReply.capabilities contains 'stream-events-attached-ack'; keep the 1 s wait only as the fallback for older gateways.
dohertj2 added the priority:p3blockedcross-repo labels 2026-11-12 07:28:19 -05:00
Author
Owner

Done on master f264977f. MxGateway Client/Contracts 0.3.0 → 0.4.0 (nupkgs committed to ./nuget-packages, as with prior bumps). GatewayGalaxySubscriber requests emit_stream_attached only when the session advertises stream-events-attached-ack; EventPump intercepts StreamAttached (never dispatched or counted; new counter galaxy.events.stream_attached; the signal also completes when the stream ends so waiters can't hang); AwaitCurrentEventStreamAsync waits on the ack within the existing 1 s StreamRequestWait budget, and logs a rate-limited Warning and proceeds if the ack is missing; older gateways keep the StreamRequested fallback. Each reconnect's new pump gets a fresh signal.

Tests: 6 new StreamAttachedAckTests (3 fail with the wait disabled); Driver.Galaxy 580/0, Galaxy.Browser 24/0, Core.Abstractions 728/0; full solution builds clean. Not covered by a unit test: the request flag reaching a real gateway. Verify on the next deploy against an mxgw at >= afd504d5 (DEV vd03's gateway is 2b13564e, older; vd03 OtOpcUa has no Galaxy driver anyway). No deployment.

Done on master f264977f. MxGateway Client/Contracts 0.3.0 → 0.4.0 (nupkgs committed to ./nuget-packages, as with prior bumps). GatewayGalaxySubscriber requests emit_stream_attached only when the session advertises stream-events-attached-ack; EventPump intercepts StreamAttached (never dispatched or counted; new counter galaxy.events.stream_attached; the signal also completes when the stream ends so waiters can't hang); AwaitCurrentEventStreamAsync waits on the ack within the existing 1 s StreamRequestWait budget, and logs a rate-limited Warning and proceeds if the ack is missing; older gateways keep the StreamRequested fallback. Each reconnect's new pump gets a fresh signal. Tests: 6 new StreamAttachedAckTests (3 fail with the wait disabled); Driver.Galaxy 580/0, Galaxy.Browser 24/0, Core.Abstractions 728/0; full solution builds clean. Not covered by a unit test: the request flag reaching a real gateway. Verify on the next deploy against an mxgw at >= afd504d5 (DEV vd03's gateway is 2b13564e, older; vd03 OtOpcUa has no Galaxy driver anyway). No deployment.
Author
Owner

Live-verified 2026-11-12 on windev (mxgw upgraded 8cb8fcdf → main 447070a5, Server + x86 Worker; backup C:\publish\mxaccessgw-backup-20261112-pre447070a5). New durable LiveIntegration test on master a28adba2: GatewayGalaxyStreamAttachedAckLiveTests (MXGW_ENDPOINT + GALAXY_MXGW_API_KEY), 4/4 against http://10.100.0.48:5120:

  • session advertises stream-events-attached-ack; ack is the first stream message (worker_sequence 0) when requested, never when not;
  • through the real driver the wire order is stream request → one ack → SubscribeBulk → data; ack counted on galaxy.events.stream_attached only, never dispatched; no missing-ack warning within the 1 s budget; static TestMachine_002.Tagname delivers its initial value;
  • control: without the ack request, the 1 s fallback still delivers.
    Mutation controls on live: subscriber not requesting → fails; driver not waiting → fails 2/2 (wire order became stream → subscribe → ack, so the race is real); pump dispatching the ack → fails.
    Existing Galaxy live tests vs the upgraded gateway: ReopenAndWrite 5/5; WriteMeter 3/3 filtered (fails only in a full parallel run, per its own doc); AlarmFeed fails only because windev has 0 active alarms.
**Live-verified 2026-11-12 on windev** (mxgw upgraded 8cb8fcdf → main 447070a5, Server + x86 Worker; backup C:\publish\mxaccessgw-backup-20261112-pre447070a5). New durable LiveIntegration test on master a28adba2: GatewayGalaxyStreamAttachedAckLiveTests (MXGW_ENDPOINT + GALAXY_MXGW_API_KEY), 4/4 against http://10.100.0.48:5120: - session advertises stream-events-attached-ack; ack is the first stream message (worker_sequence 0) when requested, never when not; - through the real driver the wire order is stream request → one ack → SubscribeBulk → data; ack counted on galaxy.events.stream_attached only, never dispatched; no missing-ack warning within the 1 s budget; static TestMachine_002.Tagname delivers its initial value; - control: without the ack request, the 1 s fallback still delivers. Mutation controls on live: subscriber not requesting → fails; driver not waiting → fails 2/2 (wire order became stream → subscribe → ack, so the race is real); pump dispatching the ack → fails. Existing Galaxy live tests vs the upgraded gateway: ReopenAndWrite 5/5; WriteMeter 3/3 filtered (fails only in a full parallel run, per its own doc); AlarmFeed fails only because windev has 0 active alarms.
dohertj2 removed the blocked label 2026-11-12 08:09:41 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#877