fix(opcua): #855 review 1 — re-decide frozen replay entries; a failed delivery is not a deferral

- QueueFrozenReplay re-asks each item's verdict right before each entry's gate
  hold (Server-object and folder cut paths): a grant revoked between the
  pre-Lock verdicts and the replay no longer lets the replay through. A denied
  entry is also removed from the cut's re-sent set.
- ReportEventWithoutBlocking logs and returns on a delivery that faulted
  inline instead of booking it as a deferral episode (which ran the drain and
  ClearStaleRefreshCuts under the event-report gate while Lock was held).
- OnConditionReportEvent isolates failures per Server-object item.
- Tests: revocation between cut and replay (folder + Server object), throwing
  hop not booked as a deferral; production-overload sampling inside Lock.

Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
This commit is contained in:
Joseph Doherty
2026-11-11 12:31:02 -05:00
parent d9b23e0b95
commit d2b1545659
3 changed files with 182 additions and 15 deletions
+5 -1
View File
@@ -924,7 +924,11 @@ Behaviours worth knowing before enabling it:
`QueueSize`) and the verdict runs on the reporter's thread, which already holds `Lock` — so a burst under one
`Lock` hold completes with nothing deferred, and the #838 deadlock shape is gone for condition events. Folder items
therefore see condition events in report order. The cost moves with it: the per-event verdict and filter for
folder items now run under `Lock` (as for Server-object items), where the SDK used to cache the verdict off it.
folder items now run under `Lock` (as for Server-object items), where the SDK used to cache the verdict off it —
including the SDK item queue's own per-event costs (its duplicate scan, and at a full queue a list shift), so many
folder items on one notifier whose clients stop publishing make each report proportionally slower under `Lock`.
With auditing on (off in this repo), a condition's SDK method **audit** event still takes the folder's channel, so
at a folder item it may now arrive after the condition event that method produced (they were one FIFO before).
- **The deferral queue and the cut stay as the safety net**, for a hop that is not ours (none exists today:
conditions are never event notifiers and variables cannot host event items) — and folder items share the cut:
a `ConditionRefresh`/`ConditionRefresh2` of a folder item takes the same two paths as the Server object (plain walk