fix(r2-10): register the tracker's production reader on driver nodes + wiring guard
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
{ "id": "T3", "subject": "Invoker: successful Execute* resets ConsecutiveFailures (TDD in CapabilityInvokerTests)", "status": "completed", "blockedBy": ["T1"] },
|
||||
{ "id": "T4", "subject": "Commons: DriverResilienceStatusChanged record + driver-resilience-status TopicName", "status": "completed", "blockedBy": [] },
|
||||
{ "id": "T5", "subject": "Host: DriverResilienceStatusPublisherService (BuildMessages mapping + 5s DPS timer shell; TDD mapping in Host.IntegrationTests)", "status": "completed", "blockedBy": ["T1", "T4"] },
|
||||
{ "id": "T6", "subject": "Host DI: register the publisher in AddOtOpcUaDriverFactories + ResilienceStatusReaderRegistrationTests wiring guard (tracker HAS a production reader)", "status": "pending", "blockedBy": ["T5"] },
|
||||
{ "id": "T6", "subject": "Host DI: register the publisher in AddOtOpcUaDriverFactories + ResilienceStatusReaderRegistrationTests wiring guard (tracker HAS a production reader)", "status": "completed", "blockedBy": ["T5"] },
|
||||
{ "id": "T7", "subject": "AdminUI: IDriverResilienceStatusStore + InMemory impl + AddOtOpcUaDriverStatusServices registration (TDD mirroring DriverStatusSnapshotStoreTests)", "status": "pending", "blockedBy": ["T4"] },
|
||||
{ "id": "T8", "subject": "AdminUI: DriverResilienceStatusBridge DPS actor + spawn in WithOtOpcUaSignalRBridges", "status": "pending", "blockedBy": ["T7"] },
|
||||
{ "id": "T9", "subject": "AdminUI: resilience chip section in DriverStatusPanel.razor (in-process store read; no bUnit — verified by T10)", "status": "pending", "blockedBy": ["T7"] },
|
||||
|
||||
@@ -70,6 +70,13 @@ public static class DriverFactoryBootstrap
|
||||
logger: sp.GetService<ILoggerFactory>()?.CreateLogger("ZB.MOM.WW.OtOpcUa.Core.Resilience.DriverCapabilityInvokerFactory"));
|
||||
});
|
||||
|
||||
// The tracker's operator-facing reader: a periodic DPS publisher that mirrors each snapshot to the
|
||||
// AdminUI resilience panel (R2-10 — closes the "tracker fed by everything, read by nothing" gap).
|
||||
// Lives on driver nodes exactly where the tracker exists. The lazy Func<ActorSystem> is idempotent
|
||||
// with the one Program.cs registers for the alarm-command router.
|
||||
services.TryAddSingleton<Func<Akka.Actor.ActorSystem>>(sp => () => sp.GetRequiredService<Akka.Actor.ActorSystem>());
|
||||
services.AddHostedService<DriverResilienceStatusPublisherService>();
|
||||
|
||||
// Driver nodes also carry the probe set so a fused admin,driver node has it; the admin-only
|
||||
// case is covered by Program.cs calling AddOtOpcUaDriverProbes() in the hasAdmin block.
|
||||
services.AddOtOpcUaDriverProbes();
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.Host.Drivers;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Host.IntegrationTests;
|
||||
|
||||
/// <summary>
|
||||
/// Guards that the resilience-status tracker now HAS a production reader — the exact
|
||||
/// "built-but-never-wired" class of bug the whole arch-review targets (mirrors
|
||||
/// <see cref="ResilienceInvokerFactoryRegistrationTests"/>). <c>AddOtOpcUaDriverFactories</c> (the
|
||||
/// driver-node bootstrap) must register <see cref="DriverResilienceStatusPublisherService"/> as an
|
||||
/// <see cref="IHostedService"/>. A refactor that drops the registration fails this test, not production.
|
||||
/// </summary>
|
||||
public sealed class ResilienceStatusReaderRegistrationTests
|
||||
{
|
||||
[Fact]
|
||||
public void AddOtOpcUaDriverFactories_registers_the_resilience_status_reader_hosted_service()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddLogging();
|
||||
services.AddOtOpcUaDriverFactories();
|
||||
|
||||
services.ShouldContain(
|
||||
d => d.ServiceType == typeof(IHostedService)
|
||||
&& d.ImplementationType == typeof(DriverResilienceStatusPublisherService),
|
||||
"the resilience-status tracker must have a production reader — the periodic DPS publisher hosted service on driver nodes");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user