docs(host): REQ-HOST-6 documents the hand-rolled HOCON bootstrap; drop unused Akka.Hosting packages

This commit is contained in:
Joseph Doherty
2026-07-08 16:59:19 -04:00
parent 48e97fee01
commit 1f1dbd916d
3 changed files with 16 additions and 18 deletions
+10 -9
View File
@@ -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.