fix(historian): live writers rethrow pass cancellation; gateway writes normalised (lmxopcua#746)
Every IHistorianValueWriter caught Exception and returned false, including
OperationCanceledException from the drain's own token. The recorder's guard
("a cancelled pass is not a tag failure") was therefore dead code: at shutdown
mid-pass each cancelled group could be booked as a consecutive failure and,
with a sibling that already wrote, tip a healthy tag toward quarantine.
SqlServer, QuestDb and Gateway writers now rethrow a cancellation of the
caller's token; a cancellation-shaped error on a live token is still an
ordinary failed write.
The Gateway writer relabelled a Local-kind timestamp as UTC instead of
converting it, so the same value could land at two different times on two
backends. Stamped samples now go through LiveWritePreparer (Local -> UTC,
non-finite doubles not sent, duplicate timestamps keep the first); unstamped
samples are still left for the gateway to stamp, in batch order.
Rebased from the unpushed remed/lane-H2 branch (originally authored 2026-10-22
in session_01Ub9hGmYLQvn9XETzw7CMsT) onto current master.
Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -219,6 +219,13 @@ source it from there.
|
||||
> it is sent (a server-managed column; 0.2.0 Contracts C-002), so **AVEVA still stores every recorded value as
|
||||
> Good** — a pre-existing limitation of that backend, now documented rather than fixed (archreview 06/C-7). The
|
||||
> `SqlServer` backend stores the real status.
|
||||
>
|
||||
> **Live writes are normalised alike on every backend.** The Gateway writer now runs each stamped sample through the SQL
|
||||
> backends' `LiveWritePreparer`: a `Local`-kind timestamp is **converted** to UTC (it used to be relabelled UTC, shifting it by
|
||||
> the node's offset), NaN / ±Infinity are not sent (the SQL backends store them as an Empty + Bad sample; the gateway's live
|
||||
> path is numeric-only), and a duplicate timestamp within a batch keeps the first. An unstamped sample is still left for the
|
||||
> gateway to stamp. Every live writer returns `false` for a failed write but **rethrows a cancellation of the drain pass**
|
||||
> (shutdown), so a node stop can never be booked as a tag failure toward the #538 quarantine.
|
||||
|
||||
> ✅ **Continuous value capture is LIVE-PROVEN END-TO-END
|
||||
> ([#491](https://gitea.dohertylan.com/dohertj2/lmxopcua/issues/491) CLOSED — gate run 2026-08-01,
|
||||
|
||||
Reference in New Issue
Block a user