fix(opcuaclient): unresolvable acks warn instead of tripping the ack breaker; shutdown holds subscription management (review r1 N-1, N-2, N-3)
- N-1 (Important): m3's BadNodeIdUnknown throw for an ack with no resolvable condition counted toward the host's AlarmAcknowledge breaker (threshold 5), so re-acks of one unresolvable condition blocked every genuine ack. It now logs a Warning and returns; only a no-reply transport failure throws. Test through the real CapabilityInvoker: six unresolvable acks, then a genuine ack that is still delivered (red with the throw restored). - N-2: ShutdownAsync holds _subscriptionGate for the whole teardown (in-flight subscribes finish first, bounded by the budget), so a subscribe arriving during the delete phase finds the session released instead of creating a subscription on the closing session. Red-tested. - N-3: the shutdown-side cert-validation detach is generation-checked under _probeLock with the map / endpoint clear. Refs #743 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -104,8 +104,10 @@ The session keep-alive (`KeepAliveInterval`, default 5 s) is the liveness signal
|
||||
no health — including a write the host cancelled at its own write deadline against a hung upstream; the session
|
||||
keep-alive owns liveness and reports that outage itself. A reply that was in flight across a bad keep-alive advances
|
||||
the stamp but does not write `Healthy` while the outage is published — the keep-alive recovery ends the outage.
|
||||
An ack none of whose condition ids resolves sends nothing and fails `BadNodeIdUnknown`; with no session an ack fails
|
||||
`BadNotConnected` (before or inside the gate alike).
|
||||
An ack none of whose condition ids resolves sends nothing and logs a Warning — it does **not** throw (a deterministic
|
||||
per-ack refusal must not count toward the host's AlarmAcknowledge circuit breaker, or five re-acks of one
|
||||
unresolvable condition would block every genuine ack). Only a call with no reply throws; with no session an ack
|
||||
fails `BadNotConnected` (before or inside the gate alike).
|
||||
- **Bad keep-alive** ⇒ health `Degraded` (`LastError = "keep-alive: <status>"`, read stamp preserved), host status
|
||||
`Stopped`, and — **once per outage**, not per keep-alive — every subscribed ref is published `BadNoCommunication`
|
||||
with its last value retained and **source + server timestamp = the detection time** (live-gate F1: stamped with the
|
||||
|
||||
Reference in New Issue
Block a user