Rewrites the active-node sections of the spec and shared contract, which described the leader-based design that both consumers rejected. - SPEC §2.3 replaced: the rule, the ordered RolePreference, why a node holding none of the preferred roles is Unhealthy rather than Healthy, and the data payload. §4 (IActiveNodeGate) and the tier table follow. - SPEC §6 marked historical: it still tells adopters to use ActiveNodeHealthCheck(role: "admin") and AkkaActiveNodeGate, which is the advice that produced the defect. Kept for provenance, annotated so nobody follows it again. - GAPS: gaps L1/L2 recorded as closed the wrong way, reopened, then closed at 0.3.0 — including the part worth remembering, that both apps adopted the shared check as specified, hit it live, and reverted to private copies, so the surface reached zero consumers by being avoided rather than unused. - Index rows updated with the consumer-visible changes and both app branches.
4.0 KiB
ZB.MOM.WW.Health
Health-check libraries for the ZB.MOM.WW SCADA family (OtOpcUa, MxAccessGateway, ScadaBridge). These are libraries, not a service — each package is linked directly into the consuming application at build time. There is no central health process or network hop; probes run in-process alongside the application.
The library normalizes the three-tier health endpoint convention (/health/ready, /health/active, /healthz) and provides reusable probe implementations so the three sister projects share a common surface without duplicating probe logic.
Built at 0.3.0 and published to the Gitea NuGet feed. Adopted by all four apps — adoption is tracked in ~/Desktop/scadaproj/components/health/GAPS.md.
Packages
| Package | Responsibilities | Key Dependencies |
|---|---|---|
ZB.MOM.WW.Health |
Core tier convention, MapZbHealth extension, canonical JSON writer (ZbHealthWriter), IActiveNodeGate seam, GrpcDependencyHealthCheck reachability probe, tier-tag constants (ZbHealthTags). No Akka or EF dependency. |
Microsoft.AspNetCore.App (framework ref), Grpc.Net.Client |
ZB.MOM.WW.Health.Akka |
AkkaClusterHealthCheck with a configurable AkkaClusterStatusPolicy (presets: Default / OtOpcUaCompat); ClusterActiveNode — the family-wide oldest-Up-member rule, optionally role-scoped; ActiveNodeHealthCheck over it (role-preference list, activeRole/activeNode in the result data); and AkkaActiveNodeGate, which backs IActiveNodeGate from the same rule. |
ZB.MOM.WW.Health, Akka.Cluster |
ZB.MOM.WW.Health.EntityFrameworkCore |
DatabaseHealthCheck<TContext> — resolves IDbContextFactory<TContext> when registered, else a scoped TContext; pool-safe. Default probe: CanConnectAsync. Optional ProbeQuery delegate for query-based validation. |
ZB.MOM.WW.Health, Microsoft.EntityFrameworkCore |
Consumer matrix
| Consumer | ZB.MOM.WW.Health (core) |
ZB.MOM.WW.Health.Akka |
ZB.MOM.WW.Health.EntityFrameworkCore |
|---|---|---|---|
| OtOpcUa | yes | yes | yes |
| MxAccessGateway | yes | — | — |
| ScadaBridge | yes | yes | yes |
MxAccessGateway consumes the core package only — it has no Akka cluster and no EF DbContext. OtOpcUa and ScadaBridge consume all three packages.
Build, test, and pack commands
# From ZB.MOM.WW.Health/
# Build
dotnet build ZB.MOM.WW.Health.slnx
dotnet build ZB.MOM.WW.Health.slnx -c Release
# Test (no external dependencies — no running Akka cluster, no database)
dotnet test ZB.MOM.WW.Health.slnx
# Pack (three .nupkg files land in artifacts/)
dotnet pack ZB.MOM.WW.Health.slnx -c Release -o ./artifacts
All three test assemblies run offline. The Akka suite forms real in-process clusters on loopback: a single-node one for the cluster-data payload, and a two-node one built so the oldest member is not the lowest-addressed one — the only condition under which age- and leader-ordering disagree, and so the only fixture that can catch a leader-based active-node regression. It binds fixed ports 19540/19541 (distinct from OtOpcUa's equivalent fixture) and carries a sanity check that the divergence actually occurred, so the assertions cannot pass for the wrong reason:
| Assembly | Tests |
|---|---|
ZB.MOM.WW.Health.Tests |
25 |
ZB.MOM.WW.Health.Akka.Tests |
45 |
ZB.MOM.WW.Health.EntityFrameworkCore.Tests |
6 |
| Total | 76 |
GeneratePackageOnBuild is off — pack explicitly with the command above.
Status
Built at 0.3.0 and published to the Gitea NuGet feed. Adopted by all four apps — adoption is tracked in the component backlog:
~/Desktop/scadaproj/components/health/GAPS.md— adoption order, effort, and risk
Design documentation:
~/Desktop/scadaproj/components/health/spec/SPEC.md— normalized three-tier target~/Desktop/scadaproj/components/health/shared-contract/ZB.MOM.WW.Health.md— proposed API (aligned to shipped code)~/Desktop/scadaproj/components/health/current-state/— per-project current state (code-verified)