using Akka.Actor;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Health;
using ZB.MOM.WW.ScadaBridge.HealthMonitoring;
using ZB.MOM.WW.ScadaBridge.Host.Actors;
namespace ZB.MOM.WW.ScadaBridge.Host;
///
/// Sends SiteHealthReport to the local SiteCommunicationActor via Akka ActorSelection,
/// which forwards it to central. The send is an acked round-trip (review 01 [Medium]):
/// it Asks and awaits the central , so a lost or
/// rejected report faults the sender's task (driving its counter-restore path).
///
public class AkkaHealthReportTransport : IHealthReportTransport
{
private readonly AkkaHostedService _akkaService;
private static readonly TimeSpan AckTimeout = TimeSpan.FromSeconds(10);
///
/// Initializes a new backed by the given Akka hosted service.
///
/// The Akka hosted service used to access the running actor system.
public AkkaHealthReportTransport(AkkaHostedService akkaService)
{
_akkaService = akkaService;
}
///
public async Task SendAsync(SiteHealthReport report, CancellationToken cancellationToken)
{
var actorSystem = _akkaService.ActorSystem
?? throw new InvalidOperationException("Actor system not started — health report not sent");
var siteComm = actorSystem.ActorSelection("/user/site-communication");
var ack = await siteComm.Ask(report, AckTimeout, cancellationToken)
.ConfigureAwait(false);
if (!ack.Accepted)
throw new InvalidOperationException($"Health report #{report.SequenceNumber} rejected: {ack.Error}");
}
}