fix(runtime): the passive half of a LocalDb pair stands its alarm drain down for its mesh partner (review R6 MINOR-4)
The drain gate's 'is my queue-sharing peer Primary?' used only the host of
LocalDb:Replication:PeerAddress, which the passive half (ApiKey +
SyncListenPort) does not set - so as Secondary it kept draining beside its
Primary partner and every alarm event reached the historian twice.
DriverHostActor takes a sharesAlarmQueueWithLocal predicate used when no
peer host is known; WithOtOpcUaRuntimeActors builds it
(BuildAlarmQueuePeerPredicate) for a SharesRowsWithPeer node with no
PeerAddress as 'a member of my own cluster-{ClusterId} mesh other than
me'. A node sharing no rows, or with no mesh role, gets none and keeps
draining. AlarmHistorian.md / Redundancy.md / pair-replication runbook
updated.
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -103,6 +103,17 @@ Two postures are deliberate:
|
||||
a key with no dial and no listener (e.g. a fleet-wide secret on an unpaired
|
||||
node) captures changes but shares them with nobody, and gating it would park
|
||||
its events behind a Primary that does not hold them (review R1 m3).
|
||||
- **A gated node stands down only for the peer that holds its rows — and BOTH
|
||||
halves of a pair know it.** The dialling half identifies its peer by the host
|
||||
of `LocalDb:Replication:PeerAddress`. The passive half (`ApiKey` +
|
||||
`SyncListenPort`, no `PeerAddress`) identifies it as its **per-cluster mesh
|
||||
partner** (the other member of its `cluster-{ClusterId}` role). Before review
|
||||
R6 MINOR-4 the passive half knew no peer at all, so as Secondary it kept
|
||||
draining beside its Primary partner and the historian received every alarm
|
||||
event twice. ⚠️ A passive half with **no** cluster-scoped role (a legacy,
|
||||
pre-Phase-6 node) still cannot identify its partner and keeps draining — it
|
||||
cannot prove which Primary holds its rows, and deferring to the wrong one
|
||||
would strand them.
|
||||
- **A gate that throws means "not now", never permission.** Draining on a gate
|
||||
fault would put a pair into dual delivery exactly when its redundancy signal is
|
||||
sick.
|
||||
|
||||
Reference in New Issue
Block a user