fix(modbus): exception-safe batch wrapper; driver batch wiring consistency

This commit is contained in:
Joseph Doherty
2026-08-15 12:27:19 -04:00
parent f81cbabd2d
commit 5c61d0b133
7 changed files with 129 additions and 9 deletions
@@ -217,6 +217,20 @@ Per-tag raising is already wired via the engine's `onChange` — leave it.
**Step 5:** `git add -A && git commit -m "feat(drivers): Modbus + S7 implement IBatchSubscribable via PollGroupEngine batch callback"`
**Deviation (landed):** Modbus does **not** forward the engine's `items` argument — it ignores it and
raises the batch from its own per-cycle buffer of the items that passed `ShouldPublish`. The engine
collects its batch list unconditionally and has no knowledge of the driver's deadband filter, so a
straight pass-through would carry changes the per-tag event suppressed, and a consumer that preferred
the batch event would see deadband silently stop working (review finding). `onBatch` is therefore used
only as the end-of-cycle signal, draining the buffer; a cycle whose every change was suppressed raises
nothing. Because that buffer is the only piece of cross-cycle state any of the four poll drivers holds,
the driver's `onChange` bridge also wraps `OnDataChange?.Invoke(...)` in a swallowing try/catch
(mirroring `PollGroupEngine.ReportError`): the engine invokes the bridge unguarded, so a throwing
external subscriber would unwind the cycle before `onBatch` ran and the undrained items would merge
into a later cycle's batch. The buffer append stays outside the catch — the item was published as far
as the batch contract is concerned; only the per-tag subscriber faulted. S7/AbCip/FOCAS forward the
engine's list as this task describes and hold no such state.
---
### Task 3b: AbCip + FOCAS raise the batch event