feat: replace ActorSelection with ClusterClient for inter-cluster communication
Central and site clusters now communicate via ClusterClient/ ClusterClientReceptionist instead of direct ActorSelection. Both CentralCommunicationActor and SiteCommunicationActor are registered with their cluster's receptionist. Central creates one ClusterClient per site using NodeA/NodeB contact points from the DB. Sites configure multiple CentralContactPoints for automatic failover between central nodes. ISiteClientFactory enables test injection.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Akka.Actor;
|
||||
using Akka.Cluster.Tools.Client;
|
||||
using Akka.Event;
|
||||
using ScadaLink.Commons.Messages.Artifacts;
|
||||
using ScadaLink.Commons.Messages.DebugView;
|
||||
@@ -11,9 +12,9 @@ using ScadaLink.Commons.Messages.RemoteQuery;
|
||||
namespace ScadaLink.Communication.Actors;
|
||||
|
||||
/// <summary>
|
||||
/// Site-side actor that receives messages from central via Akka remoting and routes
|
||||
/// Site-side actor that receives messages from central via ClusterClient and routes
|
||||
/// them to the appropriate local actors. Also sends heartbeats and health reports
|
||||
/// to central.
|
||||
/// to central via the registered ClusterClient.
|
||||
///
|
||||
/// WP-4: Routes all 8 message patterns to local handlers.
|
||||
/// </summary>
|
||||
@@ -29,10 +30,10 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
private readonly IActorRef _deploymentManagerProxy;
|
||||
|
||||
/// <summary>
|
||||
/// Optional reference to the central communication actor for sending heartbeats/health.
|
||||
/// Set via RegisterCentral message.
|
||||
/// ClusterClient reference for sending messages to the central cluster.
|
||||
/// Set via RegisterCentralClient message.
|
||||
/// </summary>
|
||||
private ActorSelection? _centralSelection;
|
||||
private IActorRef? _centralClient;
|
||||
|
||||
/// <summary>
|
||||
/// Local actor references for routing specific message patterns.
|
||||
@@ -55,7 +56,11 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
_deploymentManagerProxy = deploymentManagerProxy;
|
||||
|
||||
// Registration
|
||||
Receive<RegisterCentralPath>(HandleRegisterCentral);
|
||||
Receive<RegisterCentralClient>(msg =>
|
||||
{
|
||||
_centralClient = msg.Client;
|
||||
_log.Info("Registered central ClusterClient");
|
||||
});
|
||||
Receive<RegisterLocalHandler>(HandleRegisterLocalHandler);
|
||||
|
||||
// Pattern 1: Instance Deployment — forward to Deployment Manager
|
||||
@@ -130,7 +135,8 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
// Internal: forward health report to central
|
||||
Receive<SiteHealthReport>(msg =>
|
||||
{
|
||||
_centralSelection?.Tell(msg, Self);
|
||||
_centralClient?.Tell(
|
||||
new ClusterClient.Send("/user/central-communication", msg), Self);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -146,12 +152,6 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
_options.TransportHeartbeatInterval);
|
||||
}
|
||||
|
||||
private void HandleRegisterCentral(RegisterCentralPath msg)
|
||||
{
|
||||
_centralSelection = Context.ActorSelection(msg.CentralActorPath);
|
||||
_log.Info("Registered central communication path: {0}", msg.CentralActorPath);
|
||||
}
|
||||
|
||||
private void HandleRegisterLocalHandler(RegisterLocalHandler msg)
|
||||
{
|
||||
switch (msg.HandlerType)
|
||||
@@ -175,7 +175,7 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
|
||||
private void SendHeartbeatToCentral()
|
||||
{
|
||||
if (_centralSelection == null)
|
||||
if (_centralClient == null)
|
||||
return;
|
||||
|
||||
var hostname = Environment.MachineName;
|
||||
@@ -185,7 +185,8 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
IsActive: true,
|
||||
DateTimeOffset.UtcNow);
|
||||
|
||||
_centralSelection.Tell(heartbeat, Self);
|
||||
_centralClient.Tell(
|
||||
new ClusterClient.Send("/user/central-communication", heartbeat), Self);
|
||||
}
|
||||
|
||||
// ── Internal messages ──
|
||||
@@ -194,9 +195,9 @@ public class SiteCommunicationActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command to register the central communication actor path for outbound messages.
|
||||
/// Command to register a ClusterClient for communicating with the central cluster.
|
||||
/// </summary>
|
||||
public record RegisterCentralPath(string CentralActorPath);
|
||||
public record RegisterCentralClient(IActorRef Client);
|
||||
|
||||
/// <summary>
|
||||
/// Command to register a local actor as a handler for a specific message pattern.
|
||||
|
||||
Reference in New Issue
Block a user