feat(comm): Phase 4 — delete Akka ClusterClient site↔central transport, gRPC-only
ClusterClient→gRPC migration Phase 4 (docs/plans/2026-07-22-clusterclient-to-grpc-plan.md). Phases 2/3 proved both directions on gRPC; this removes the Akka transport underneath. Deleted: - AkkaCentralTransport, AkkaSiteTransport (+ their dedicated tests) - ISiteClientFactory + DefaultSiteClientFactory; CentralCommunicationActor legacy ctor + SelectTransport (Host now builds GrpcSiteTransport and injects it) - ClusterClient creation + both ClusterClientReceptionist.RegisterService calls in AkkaHostedService; the RegisterCentralClient message + receive block - CommunicationOptions.CentralContactPoints; the CentralTransport/SiteTransport coexistence flags; the CentralTransportMode/SiteTransportKind enums gRPC is now the only site↔central transport (site→central CentralControlService via GrpcCentralTransport; central→site SiteCommandService via GrpcSiteTransport), both built unconditionally by the Host. NoOpCentralTransport is the fail-loud null-default so TestKit command-dispatch suites still construct the site actor without a wired transport; production always injects GrpcCentralTransport. Config: CentralGrpcEndpoints is now unconditional — CommunicationOptionsValidator rejects blank entries (role-agnostic), and StartupValidator requires a Site node to list >=1 endpoint (fail-fast, mirrors GrpcPsk). Rig configs moved CentralContactPoints -> CentralGrpcEndpoints (docker x6, docker-env2 x2, Host default, deploy/wonder-app-vd03). Kept Akka.Cluster.Tools (ClusterSingleton still used). Tests: build 0/0; Communication.Tests 640, Host.Tests 421 green. Removed the ClusterClient.Send per-site-routing tests (covered by the transport suites), swapped the ISiteClientFactory-based ctors to a substitute ISiteCommandTransport, converted the audit-push integration relay to an in-process bridge transport. Docs: Component-Communication/Host/StoreAndForward, components/Communication, topology-guide, grpc_streams (SUPERSEDED note), the frame-size known-issue (retired amendment), and CLAUDE.md transport decisions. Not included: the dead IntegrationCallRequest path (#32) is a separate user-owned behavioral decision — SiteEnvelope routing is transport-agnostic so it still compiles.
This commit is contained in:
@@ -1,51 +1,16 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.Communication;
|
||||
|
||||
/// Which transport carries the seven site→central control messages. Selected per node by
|
||||
/// <c>ScadaBridge:Communication:CentralTransport</c>; the migration ships with
|
||||
/// <see cref="Akka"/> as the default so nothing flips until a node opts in.
|
||||
/// </summary>
|
||||
public enum CentralTransportMode
|
||||
{
|
||||
/// <summary>Akka <c>ClusterClient</c> — the transport in production today, and the default.</summary>
|
||||
Akka = 0,
|
||||
|
||||
/// <summary>gRPC dial of the central <c>CentralControlService</c> (Phase 1A migration target).</summary>
|
||||
Grpc = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects the transport the central→site command plane rides on. The Akka
|
||||
/// per-site <c>ClusterClient</c> path is the default until the gRPC cutover
|
||||
/// (ClusterClient→gRPC migration, Phase 1B); flipping to <see cref="Grpc"/> is the
|
||||
/// rollback-by-flag switch.
|
||||
/// </summary>
|
||||
public enum SiteTransportKind
|
||||
{
|
||||
/// <summary>Route <c>SiteEnvelope</c>s through the per-site Akka <c>ClusterClient</c> (today's default).</summary>
|
||||
Akka,
|
||||
|
||||
/// <summary>Route <c>SiteEnvelope</c>s over the site <c>SiteCommandService</c> gRPC plane.</summary>
|
||||
Grpc
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration options for central-site communication, including per-pattern
|
||||
/// timeouts and transport heartbeat settings.
|
||||
/// </summary>
|
||||
public class CommunicationOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Which transport carries the site→central control messages. Default <see cref="CentralTransportMode.Akka"/>
|
||||
/// (ClusterClient) — coexistence rule: a node flips to gRPC only by setting this to <c>Grpc</c>,
|
||||
/// and rollback is flipping it back. Selecting <c>Grpc</c> requires <see cref="CentralGrpcEndpoints"/>.
|
||||
/// </summary>
|
||||
public CentralTransportMode CentralTransport { get; set; } = CentralTransportMode.Akka;
|
||||
|
||||
/// <summary>
|
||||
/// Central control-plane gRPC endpoints (preferred first), e.g.
|
||||
/// <c>["http://scadabridge-central-a:8083", "http://scadabridge-central-b:8083"]</c>. Dialled by
|
||||
/// <see cref="Grpc.CentralChannelProvider"/> with sticky failover/failback. Required when
|
||||
/// <see cref="CentralTransport"/> is <see cref="CentralTransportMode.Grpc"/>, ignored otherwise.
|
||||
/// <see cref="Grpc.CentralChannelProvider"/> with sticky failover/failback. Required on every site
|
||||
/// node — gRPC (<c>CentralControlService</c>) is the only site→central transport.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sites reach central by container/host name, NOT via Traefik (which is HTTP/1 only; gRPC is
|
||||
@@ -53,15 +18,6 @@ public class CommunicationOptions
|
||||
/// </remarks>
|
||||
public List<string> CentralGrpcEndpoints { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Which transport the central→site command plane uses. Default <see cref="SiteTransportKind.Akka"/>
|
||||
/// (the per-site ClusterClient path) — flipping to <see cref="SiteTransportKind.Grpc"/> moves
|
||||
/// every <c>SiteEnvelope</c> onto the site <c>SiteCommandService</c> gRPC plane. Selected inside
|
||||
/// <c>CentralCommunicationActor</c>; <c>CommunicationService</c> and <c>SiteCallAuditActor</c>
|
||||
/// are unchanged either way. Rollback at any point = flip this back to <c>Akka</c>.
|
||||
/// </summary>
|
||||
public SiteTransportKind SiteTransport { get; set; } = SiteTransportKind.Akka;
|
||||
|
||||
/// <summary>Timeout for deployment commands (typically longest due to apply logic).</summary>
|
||||
public TimeSpan DeploymentTimeout { get; set; } = TimeSpan.FromMinutes(2);
|
||||
|
||||
@@ -91,12 +47,6 @@ public class CommunicationOptions
|
||||
/// </summary>
|
||||
public TimeSpan NotificationForwardTimeout { get; set; } = TimeSpan.FromSeconds(30);
|
||||
|
||||
/// <summary>
|
||||
/// Contact point addresses for the central cluster (e.g. "akka.tcp://scadabridge@central-a:8081").
|
||||
/// Used by site nodes to create a ClusterClient for reaching central.
|
||||
/// </summary>
|
||||
public List<string> CentralContactPoints { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Preshared key authenticating this node's gRPC control plane — the site↔central
|
||||
/// boundary. On a site node this is the key its inbound gate
|
||||
|
||||
Reference in New Issue
Block a user