using Akka.Actor;
using Akka.Cluster.Tools.PublishSubscribe;
using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Runtime.Telemetry;
namespace ZB.MOM.WW.OtOpcUa.Runtime.Drivers;
///
/// Forwards transitions to the cluster-wide
/// driver-health DistributedPubSub topic. Consumed by the AdminUI
/// DriverStatusSignalRBridge.
///
public sealed class AkkaDriverHealthPublisher : IDriverHealthPublisher
{
/// The DistributedPubSub topic name for driver-health snapshots — single source
/// of truth on the message contract itself.
public const string TopicName = DriverHealthChanged.TopicName;
private readonly ActorSystem _system;
private readonly ITelemetryLocalHub _hub;
/// Initializes a new instance of .
/// The Akka actor system used to resolve the DPS mediator.
/// The node-local live-telemetry hub each snapshot is also emitted into (Phase 5).
public AkkaDriverHealthPublisher(ActorSystem system, ITelemetryLocalHub hub)
{
_system = system;
_hub = hub;
}
///
public void Publish(string clusterId, string driverInstanceId, DriverHealth health, int errorCount5Min)
{
var msg = new DriverHealthChanged(
clusterId,
driverInstanceId,
health.State.ToString(),
health.LastSuccessfulRead,
health.LastError,
errorCount5Min,
DateTime.UtcNow);
DistributedPubSub.Get(_system).Mediator.Tell(new Publish(TopicName, msg));
// Phase 5: fan the same snapshot into the node-local live-telemetry hub (no-op until a gRPC
// client subscribes). The DPS publish above is unchanged — the hub is a strictly additive tap.
_hub.Emit(new TelemetryItem.Health(msg));
}
}