diff --git a/docs/DriverLifecycle.md b/docs/DriverLifecycle.md index ce77f088..60320bc8 100644 --- a/docs/DriverLifecycle.md +++ b/docs/DriverLifecycle.md @@ -476,7 +476,7 @@ forces a fresh `PollGroupEngine` subscription whose initial poll runs `forceRais the initial push added by 05/STAB-18. What the host does instead is **audit** it — `CommsRecoveryAudit` fires `DefaultCommsRecoveryAuditDelay` (30 s) after the driver reconnects and reports any ref still latched Bad, as a Warning naming the driver plus the `otopcua.driver.comms_latched_refs` counter (tagged -`driver`, `driver_type`). That counter going non-zero means a driver reconnected without re-publishing — +`driver_instance`, `driver_type`). That counter going non-zero means a driver reconnected without re-publishing — a push driver missing its initial push, or a value-only dedup swallowing an unchanged value. It is a tripwire, not a repair: nothing downstream depends on it. diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs index dd56ab17..d27c437b 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs @@ -1540,7 +1540,7 @@ public sealed class DriverHostActor : ReceiveActor, IWithTimers, IWithUnboundedS var driverType = _children.TryGetValue(msg.DriverInstanceId, out var child) ? child.DriverType : "unknown"; OtOpcUaTelemetry.DriverCommsLatchedRefs.Add( latched.Count, - new KeyValuePair("driver", msg.DriverInstanceId), + new KeyValuePair("driver_instance", msg.DriverInstanceId), new KeyValuePair("driver_type", driverType)); _log.Warning( diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorCommsLossValueNodesTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorCommsLossValueNodesTests.cs index 1454c1ea..ed1d5f0e 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorCommsLossValueNodesTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostActorCommsLossValueNodesTests.cs @@ -149,8 +149,8 @@ public sealed class DriverHostActorCommsLossValueNodesTests : RuntimeActorTestBa // Two REFS, not three nodes: the latch is keyed by RawPath, and the UNS mirror shares its // backing tag's ref — the operator is being told how many tags did not come back, not how many // address-space nodes they project onto. - AwaitCondition(() => meter.WithTag("driver", SilentDriver) > 0, TimeSpan.FromSeconds(5)); - meter.SumWithTag("driver", SilentDriver).ShouldBe(2); + AwaitCondition(() => meter.WithTag("driver_instance", SilentDriver) > 0, TimeSpan.FromSeconds(5)); + meter.SumWithTag("driver_instance", SilentDriver).ShouldBe(2); } /// @@ -190,7 +190,7 @@ public sealed class DriverHostActorCommsLossValueNodesTests : RuntimeActorTestBa publish.ExpectMsg(PresenceBudget); }); - meter.WithTag("driver", RepublishingDriver).ShouldBe(0); + meter.WithTag("driver_instance", RepublishingDriver).ShouldBe(0); } /// @@ -227,8 +227,8 @@ public sealed class DriverHostActorCommsLossValueNodesTests : RuntimeActorTestBa publish.ExpectMsg(PresenceBudget); }); - AwaitCondition(() => meter.WithTag("driver", PartialDriver) > 0, TimeSpan.FromSeconds(5)); - meter.SumWithTag("driver", PartialDriver).ShouldBe(1, "only the ref that never came back is reported"); + AwaitCondition(() => meter.WithTag("driver_instance", PartialDriver) > 0, TimeSpan.FromSeconds(5)); + meter.SumWithTag("driver_instance", PartialDriver).ShouldBe(1, "only the ref that never came back is reported"); } /// diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostCommsLossRecoveryTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostCommsLossRecoveryTests.cs index 4f67cc1b..a2d0b711 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostCommsLossRecoveryTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/Drivers/DriverHostCommsLossRecoveryTests.cs @@ -80,7 +80,7 @@ public sealed class DriverHostCommsLossRecoveryTests : RuntimeActorTestBase // …and the audit finds nothing outstanding. EventFilter.Warning(contains: "still BadNoCommunication") .Expect(0, AuditDelay + TimeSpan.FromSeconds(3), () => { }); - meter.SumWithTag("driver", "drv-recover").ShouldBe(0); + meter.SumWithTag("driver_instance", "drv-recover").ShouldBe(0); } /// @@ -109,7 +109,7 @@ public sealed class DriverHostCommsLossRecoveryTests : RuntimeActorTestBase }); // One ref (the raw tag); its UNS mirror shares it. - AwaitCondition(() => meter.SumWithTag("driver", "drv-silent") == 1, TimeSpan.FromSeconds(5)); + AwaitCondition(() => meter.SumWithTag("driver_instance", "drv-silent") == 1, TimeSpan.FromSeconds(5)); driver.SubscribeCount.ShouldBeGreaterThanOrEqualTo(2, "the child must actually have re-subscribed — otherwise this proves nothing about the push"); }