From 1f1dbd916dc1c8ec136ff9e5c4bc1b48ab741fbf Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 8 Jul 2026 16:59:19 -0400 Subject: [PATCH] docs(host): REQ-HOST-6 documents the hand-rolled HOCON bootstrap; drop unused Akka.Hosting packages --- Directory.Packages.props | 3 --- docs/requirements/Component-Host.md | 19 ++++++++++--------- .../ZB.MOM.WW.ScadaBridge.Host.csproj | 12 ++++++------ 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index b7e8dd73..b81ebba2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,11 +7,8 @@ - - - diff --git a/docs/requirements/Component-Host.md b/docs/requirements/Component-Host.md index 2f924366..de5883ae 100644 --- a/docs/requirements/Component-Host.md +++ b/docs/requirements/Component-Host.md @@ -13,7 +13,7 @@ All nodes (central and site). - Serve as the single entry point (`Program.cs`) for the ScadaBridge process. - Read and validate node configuration at startup before any actor system is created. - Register the correct set of component services and actors based on the configured node role. -- Bootstrap the Akka.NET actor system with Remoting, Clustering, and split-brain resolution via Akka.Hosting. +- Bootstrap the Akka.NET actor system with Remoting, Clustering, and split-brain resolution from a hand-assembled, injection-safe HOCON document (`AkkaHostedService.BuildHocon`; see REQ-HOST-6). - Host ASP.NET Core web endpoints on central nodes only. - Configure structured logging (Serilog) with environment-specific enrichment. - Support running as a Windows Service in production and as a console application during development. @@ -105,13 +105,15 @@ The Host must support running as a Windows Service via `UseWindowsService()`. Wh ### REQ-HOST-6: Akka.NET Bootstrap -The Host must configure the Akka.NET actor system using Akka.Hosting with: +The Host bootstraps the Akka.NET actor system from a **hand-assembled, injection-safe HOCON document** (`AkkaHostedService.BuildHocon`) passed to `ActorSystem.Create` — **not** Akka.Hosting's `AkkaConfigurationBuilder`/`AddAkka()`. Every interpolated value is routed through `QuoteHocon`/`DurationHocon` so a hostname, seed URI or strategy containing a quote, backslash or whitespace cannot corrupt the document, and each timing is rendered in milliseconds so sub-second values survive. The bound `ClusterOptions`/`NodeOptions`/`CommunicationOptions` are startup-validated (`ClusterOptionsValidator`, `StartupValidator`) so a misconfiguration fails fast with a key-naming message. The document configures: -- **Remoting**: Configured with the node's hostname and port from `NodeConfiguration`. -- **Clustering**: Configured with seed nodes and the node's cluster role from configuration. -- **Persistence**: Configured with the appropriate journal and snapshot store (SQL for central, SQLite for site). -- **Split-Brain Resolver**: Configured with the strategy and stable-after duration from `ClusterConfiguration`. -- **Actor registration**: Each component's actors registered via its `AddXxxActors()` extension method, conditional on the node's role. +- **Remoting**: the node's hostname and port from `NodeOptions`. +- **Clustering**: seed nodes and the node's cluster role(s) from configuration. +- **Split-Brain Resolver**: the strategy, stable-after and `down-if-alone` from `ClusterOptions`, **with the downing provider named explicitly** (`akka.cluster.downing-provider-class = "Akka.Cluster.SBR.SplitBrainResolverProvider, Akka.Cluster"`). Akka's default is `NoDowning`, under which the entire SBR section is inert and singletons never migrate on a crash or partition — omitting this one line silently disables failover. This exact omission was arch-review 01's Critical finding; it is now guarded by tests asserting the parsed HOCON key **and** a two-node kill test asserting the behavior (downing + singleton migration). +- **Coordinated shutdown**: `run-coordinated-shutdown-when-down = on` plus a cluster-leave phase timeout above the singleton drain budget (see REQ-HOST-4a / the down-if-alone recovery contract in Component-ClusterInfrastructure.md). +- **Actor registration**: each component's actors registered conditional on the node's role. + +> **Bootstrap-mechanism note.** The `Akka.Hosting` / `Akka.Cluster.Hosting` / `Akka.Remote.Hosting` typed-builder packages were referenced but unused and were dropped (arch-review 01 Task 22). The hand-rolled HOCON path is a single hardened, production-shape code path with full test coverage; migrating to Akka.Hosting's typed options is deliberately **not** done here and is tracked as possible future work rather than carried as an unused dependency. Only `Akka.Cluster.Tools` (ClusterSingleton/ClusterClient, transitively Akka.Cluster) remains. > **Persistence note.** ScadaBridge does not use Akka.Persistence. Durable state > (store-and-forward buffers, site event logs, static attribute writes, @@ -203,8 +205,7 @@ The Host's `Program.cs` calls these extension methods; the component libraries o ## Dependencies - **All 19 component libraries**: The Host references every component project to call their extension methods (excludes CLI, which is a separate executable). Audit Log (#23) ships its central+site code in `ZB.MOM.WW.ScadaBridge.AuditLog`; the Host calls `AddAuditLog()` on both roles, M2+ will add `AddAuditLogActors()`. -- **Akka.Hosting**: For `AddAkka()` and the hosting configuration builder. -- **Akka.Remote.Hosting, Akka.Cluster.Hosting**: For Akka subsystem configuration. (No Akka.Persistence plugin — see the Persistence note under REQ-HOST-6.) +- **Akka.Cluster.Tools**: ClusterSingleton (singleton manager/proxy) and ClusterClient/ClusterClientReceptionist; transitively pulls Akka.Cluster (SBR provider) and Akka.Remote. The actor system is built from hand-assembled HOCON (REQ-HOST-6), so the `Akka.Hosting`/`Akka.Remote.Hosting`/`Akka.Cluster.Hosting` typed-builder packages are **not** referenced (dropped in arch-review 01 Task 22). No Akka.Persistence plugin — see the Persistence note under REQ-HOST-6. - **Serilog.AspNetCore**: For structured logging integration. - **Microsoft.Extensions.Hosting.WindowsServices**: For Windows Service support. - **ASP.NET Core** (central only): For web endpoint hosting. diff --git a/src/ZB.MOM.WW.ScadaBridge.Host/ZB.MOM.WW.ScadaBridge.Host.csproj b/src/ZB.MOM.WW.ScadaBridge.Host/ZB.MOM.WW.ScadaBridge.Host.csproj index 324751a1..06d08817 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Host/ZB.MOM.WW.ScadaBridge.Host.csproj +++ b/src/ZB.MOM.WW.ScadaBridge.Host/ZB.MOM.WW.ScadaBridge.Host.csproj @@ -12,10 +12,13 @@ - + - - runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -25,9 +28,6 @@ - -