From 30356803e77f9afb97bae8c9cfd7056e6d2dc68d Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 13 Jul 2026 10:34:24 -0400 Subject: [PATCH] =?UTF-8?q?docs(docker):=20mark=20failover-drill=20results?= =?UTF-8?q?=20table=20PENDING=20=E2=80=94=20live=20drill=20run=20(plan=20R?= =?UTF-8?q?2-01=20T3)=20deferred=20to=20avoid=20disrupting=20the=20running?= =?UTF-8?q?=20docker=20cluster?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docker/README.md b/docker/README.md index f64f19bf..1920f3d3 100644 --- a/docker/README.md +++ b/docker/README.md @@ -286,12 +286,14 @@ The drill exercises S1 (SBR downing on hard crash), S3 (single active node route **Seed-node bootstrap constraint.** Only the FIRST seed in `Cluster:SeedNodes` may self-join to form a *new* cluster. Both central nodes list `scadabridge-central-a` first (`docker/central-node-a/appsettings.Central.json`, `docker/central-node-b/appsettings.Central.json`), so a lone restarted `central-b` (with `central-a` still down) loops on `InitJoin` forever — it never reaches `Up`, and `/health/active` never returns 200. Operator recovery actions: **(1)** restart the dead first-seed node (`central-a`) — preferred; or **(2)** restart the survivor with a self-first seed override (env `ScadaBridge__Cluster__SeedNodes__0=akka.tcp://scadabridge@:8081`, `ScadaBridge__Cluster__SeedNodes__1=`). The repo deliberately does NOT ship self-first ordering per node: with *both* nodes self-first, a simultaneous cold start can let each self-join independently → two one-node clusters that never merge (the cold-start split-brain the identical-seed-order convention exists to prevent). The real remedy is the pending keep-oldest topology/strategy decision (deferred, owner: user). -> **Observed results** (recorded by plan R2-01 T3, cluster @ commit ): +> **Observed results** (plan R2-01 T3): +> +> **PENDING — live drill not yet executed** (requires a dedicated docker cluster rebuild; deferred to avoid disrupting the running environment). The two-mode drill script and its per-direction PASS criteria are in place; the empirical timings below are to be filled by running `DRILL_MODE=standby` then `DRILL_MODE=active` against a freshly-deployed cluster and recording the one-line summaries + the cluster commit SHA. > > | Direction (`DRILL_MODE`) | Outcome | Measured | > |--------------------------|---------|----------| -> | `standby` (younger-node crash) | _pending T3_ | _pending T3_ | -> | `active` (oldest-node crash) | _pending T3_ | _pending T3_ | +> | `standby` (younger-node crash) | _pending live run_ | _pending live run_ | +> | `active` (oldest-node crash) | _pending live run_ | _pending live run_ | ### Central Failover