Files
lmxopcua/tests/Server
Joseph Doherty 5cb0e72166 feat(mesh): node subscribers accept EventStream commands; _coordinatorOverride -> _ackRouter
Phase 2 Task 5. DriverHostActor and ScriptedAlarmHostActor now subscribe to the
node-local EventStream alongside their existing DPS topic subscriptions, so the
transport flag lives ENTIRELY on the publishing side -- exactly one of the two
ever publishes, and the switch can be flipped or reverted without touching a
single subscriber.

Note the alarm case is not symmetric: the DPS subscribe there still carries the
node-LOCAL publisher (OtOpcUaServerHostedService's OPC UA Part 9 method calls),
which never crosses the boundary and stays on DPS in both modes. Only the
central AdminUI leg moves.

Renamed DriverHostActor._coordinatorOverride to _ackRouter. Under ClusterClient
mode that ref is the NodeCommunicationActor, emphatically not a coordinator,
and the old name would send the next reader looking for one.

Adds two wiring tests, because the unit tests either side of this seam BOTH pass
with the subscription deleted -- the comm actor's test asserts a probe receives
the message, and the host tests drive the actor by direct Tell. Neither notices
a missing PreStart subscribe. Sabotage-verified: deleting either subscription
reddens exactly its own wiring test and nothing else.

Three things went wrong while writing those tests, all worth keeping:

- The first version raced. ActorOf returns before PreStart runs, and an
  EventStream.Publish with no subscriber is dropped silently -- no buffering, no
  dead letter. Fixed with a warm-up whose ack proves PreStart completed; the
  comment says why it is not ceremony.
- The alarm version was VACUOUS: it told the host directly INSIDE the assertion
  window alongside the relay, so the direct Tell alone produced the log the
  assertion waited for. Split into warm-up (outside) and relay (inside).
- The alarm test needs its own ActorSystem: the shared harness pins
  loglevel = WARNING and the only signal an unowned alarm gives is a Debug line.

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
2026-07-22 12:19:29 -04:00
..