fix(opcua): trace every rebuild path; align history tests with the B7 contract

B6 moved the address-space-rebuild span into ApplyPlan, so the two rebuilds
that complete synchronously on the actor thread (no applier -> raw-sink
rebuild; no artifact bytes -> held) stopped emitting it
(OtOpcUaTelemetryHookTests.RebuildAddressSpace_starts_an_address_space_rebuild_span).
Both now open their own span.

B7 (late HistorianDataSource / HistorianDataUpdater re-evaluate the
capability bits) reversed three tests that pinned the old "fixed at
materialisation" contract. Re-expressed against the new one, end to end:
- events: a folder promoted without a source is unsupported, then served
  once a source is wired (source reached);
- in-process HistoryUpdate: clearing the updater retracts HistoryWrite and
  the old updater is never reached;
- over the wire: a late updater lights HistoryWrite and an insert reaches
  it; a reset retracts the bit and the insert is BadHistoryOperationUnsupported.

Refs #732
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
Joseph Doherty
2026-10-22 13:29:07 -04:00
parent be22b48b1d
commit 0117e1501b
4 changed files with 55 additions and 26 deletions
@@ -516,6 +516,10 @@ public sealed class OpcUaPublishActor : ReceiveActor, IWithTimers
// real driver node that has an applier (that node diff-and-applies from its in-hand bytes below).
if (_applier is null)
{
// Every rebuild is traced, whichever path completes it: the applier path opens its span in ApplyPlan
// (the actor-thread half), the two synchronous completions below open their own.
using var span = OtOpcUaTelemetry.StartAddressSpaceRebuildSpan();
span?.SetTag("otopcua.correlation_id", msg.Correlation.ToString());
(bool Degraded, string? Reason) outcome;
try
{
@@ -541,6 +545,8 @@ public sealed class OpcUaPublishActor : ReceiveActor, IWithTimers
// supply a real one. Leaving _lastApplied intact means the retry diffs against what is materialised.
if (msg.Artifact is null or { Length: 0 })
{
using var span = OtOpcUaTelemetry.StartAddressSpaceRebuildSpan();
span?.SetTag("otopcua.correlation_id", msg.Correlation.ToString());
if (_hasAppliedComposition)
_log.Warning(
"OpcUaPublish: no usable artifact for deployment {Id} (correlation={Correlation}) — KEEPING the currently served address space rather than tearing it down",