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:
@@ -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"
|
||||
|
||||
@@ -84,16 +84,19 @@ public static class ServiceCollectionExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the <see cref="ClusterOptions"/> for the fused-host cluster, including the
|
||||
/// <b>activating</b> split-brain-resolver registration.
|
||||
/// Builds the <see cref="ClusterOptions"/> for the fused-host cluster, setting the split-brain-resolver
|
||||
/// strategy <b>explicitly in code</b>.
|
||||
///
|
||||
/// The <c>split-brain-resolver</c> HOCON block in <c>Resources/akka.conf</c> is inert on its own —
|
||||
/// Akka.NET only runs the resolver when a downing provider is registered, otherwise the cluster
|
||||
/// falls back to <b>NoDowning</b> and a hard-crashed node is never downed (singletons and the
|
||||
/// <c>driver</c> role-leader never fail over, and a partition leaves both redundancy sides at
|
||||
/// ServiceLevel 240 forever). Setting <see cref="ClusterOptions.SplitBrainResolver"/> is what
|
||||
/// activates <c>Akka.Cluster.SBR.SplitBrainResolverProvider</c> under the hood — this is the piece
|
||||
/// that was missing (arch-review 03/S1).
|
||||
/// <b>Activation note (arch-review 03/S1, corrected):</b> Akka.Cluster.Hosting's <c>WithClustering</c>
|
||||
/// already enables an SBR downing provider <b>by default</b> — when <see cref="ClusterOptions.SplitBrainResolver"/>
|
||||
/// is <c>null</c> it applies <c>SplitBrainResolverOption.Default</c>, which registers
|
||||
/// <c>Akka.Cluster.SBR.SplitBrainResolverProvider</c> and reads the <c>split-brain-resolver</c> HOCON block in
|
||||
/// <c>Resources/akka.conf</c>. So the cluster was <b>not</b> running <c>NoDowning</c> before this option was
|
||||
/// set: the pre-existing akka.conf <c>keep-oldest</c> block was already active, and hard-crashed nodes already
|
||||
/// failed over. Setting this typed option makes the strategy <b>explicit in code</b> (independent of the
|
||||
/// framework default) rather than being the sole activator — it is reinforcing/belt-and-suspenders and
|
||||
/// produces the same effective behavior. (Only an <i>explicit</i> <c>NoDowning</c>, e.g.
|
||||
/// <c>downing-provider-class = ""</c>, would disable failover.)
|
||||
///
|
||||
/// <see cref="KeepOldestOption"/> with <c>DownIfAlone=true</c> mirrors the HOCON intent and is the
|
||||
/// correct strategy for a 2-node warm-redundancy pair: on an even split the oldest member (typically
|
||||
@@ -103,7 +106,7 @@ public static class ServiceCollectionExtensions
|
||||
/// typed option cannot express it (it must stay ≥ <c>failure-detector.acceptable-heartbeat-pause</c>).
|
||||
/// </summary>
|
||||
/// <param name="options">The bound cluster options carrying seed nodes and roles.</param>
|
||||
/// <returns>The cluster options with seed nodes, roles, and the activated split-brain resolver.</returns>
|
||||
/// <returns>The cluster options with seed nodes, roles, and the explicit split-brain-resolver strategy.</returns>
|
||||
public static ClusterOptions BuildClusterOptions(AkkaClusterOptions options)
|
||||
{
|
||||
return new ClusterOptions
|
||||
|
||||
Reference in New Issue
Block a user