42 lines
1.7 KiB
C#
42 lines
1.7 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 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 <see cref="SiteHealthReportAck"/>, so a lost or
|
|
/// rejected report faults the sender's task (driving its counter-restore path).
|
|
/// </summary>
|
|
public class AkkaHealthReportTransport : IHealthReportTransport
|
|
{
|
|
private readonly AkkaHostedService _akkaService;
|
|
|
|
private static readonly TimeSpan AckTimeout = TimeSpan.FromSeconds(10);
|
|
|
|
/// <summary>
|
|
/// Initializes a new <see cref="AkkaHealthReportTransport"/> backed by the given Akka hosted service.
|
|
/// </summary>
|
|
/// <param name="akkaService">The Akka hosted service used to access the running actor system.</param>
|
|
public AkkaHealthReportTransport(AkkaHostedService akkaService)
|
|
{
|
|
_akkaService = akkaService;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
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<SiteHealthReportAck>(report, AckTimeout, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
if (!ack.Accepted)
|
|
throw new InvalidOperationException($"Health report #{report.SequenceNumber} rejected: {ack.Error}");
|
|
}
|
|
}
|