docs(archreview #11): correct Critical 1 premise — SBR was already active on master, not NoDowning

Akka.Cluster.Hosting's WithClustering enables an SBR downing provider by default
(applies SplitBrainResolverOption.Default when ClusterOptions.SplitBrainResolver is
null), which reads the pre-existing akka.conf keep-oldest block. So the cluster was
NOT running NoDowning before Critical 1 and hard-crash failover already worked — the
typed KeepOldestOption is reinforcing/explicit-in-code, not the sole activator.

Corrects the inaccurate 'HOCON inert / NoDowning / never fails over' framing in:
- ServiceCollectionExtensions.BuildClusterOptions XML comment
- akka.conf split-brain-resolver comment
- docs/Redundancy.md Split-brain section
- SplitBrainResolverActivationTests summary + assertion message (+ method rename)

No code revert (the typed option is correct belt-and-suspenders). Cluster.Tests 29/29.
Surfaced by the #9 hard-kill failover negative control.
This commit is contained in:
Joseph Doherty
2026-07-08 22:34:20 -04:00
parent a25c9ed097
commit eaf78aad90
4 changed files with 49 additions and 37 deletions
@@ -37,12 +37,13 @@ akka {
roles = []
min-nr-of-members = 1
# Split-brain resolver. This HOCON block is the TUNING source only — it does NOT
# activate the resolver. Activation happens in code via the typed
# ClusterOptions.SplitBrainResolver (KeepOldestOption { DownIfAlone = true }) set in
# ServiceCollectionExtensions.BuildClusterOptions; without that the cluster runs Akka's
# default NoDowning and hard-crashed nodes never fail over (arch-review 03/S1).
# active-strategy + keep-oldest.down-if-alone below MUST match the typed option.
# Split-brain resolver (arch-review 03/S1). This block IS active: Akka.Cluster.Hosting's
# WithClustering enables an SBR downing provider by default (it applies
# SplitBrainResolverOption.Default when ClusterOptions.SplitBrainResolver is null), and that
# provider reads this block. ServiceCollectionExtensions.BuildClusterOptions additionally sets
# the typed KeepOldestOption { DownIfAlone = true } to make the strategy EXPLICIT in code —
# its active-strategy + keep-oldest.down-if-alone MUST match this block. (The cluster is NOT
# NoDowning; only an explicit downing-provider-class = "" would disable failover.)
# stable-after must stay >= failure-detector.acceptable-heartbeat-pause (10s) + margin.
split-brain-resolver {
active-strategy = "keep-oldest"