diff options
| -rw-r--r-- | src/config/mod.rs | 9 | ||||
| -rw-r--r-- | src/swarm/members.rs | 9 |
2 files changed, 14 insertions, 4 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs index 418c8e3..c5b2dad 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -254,7 +254,7 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[ Kind::Duration, "DURATION", Some("7d"), - "Members that renewed their alive stamp within this time vote on remakes (a majority of them must agree). Matters on the node that coordinates a remake.", + "Members that renewed their alive stamp within this time vote on remakes (a majority of them must agree). At least 7h (members renew every seventh of their own window, hourly at most); the same on every node, or a coordinator with a shorter one counts fewer members.", ), option( "clock-skew-warn", @@ -748,8 +748,11 @@ impl Settings { if !(1024..=4 << 20).contains(&self.blob_chunk) { bail!("blob-chunk must be between 1KiB and 4MiB"); } - if self.electorate_window.is_zero() { - bail!("electorate-window must be longer than 0"); + // Members renew their alive stamp hourly at most (`members::alive_renewal`): in + // a shorter window, live members would drop out between renewals, down to an + // electorate of the coordinator alone. + if self.electorate_window < crate::swarm::members::MIN_ELECTORATE_WINDOW { + bail!("electorate-window must be at least 7h (seven hourly renewals)"); } if let Some(alias) = &self.alias { check_alias(alias)?; diff --git a/src/swarm/members.rs b/src/swarm/members.rs index 6be523c..098c767 100644 --- a/src/swarm/members.rs +++ b/src/swarm/members.rs @@ -229,9 +229,16 @@ pub(crate) fn electorate(doc: &impl ReadDoc, now_ms: u64, window: Duration) -> V /// drops out of the electorate (a seventh of the window), but at most hourly and at /// least daily, so idle swarms stay quiet. fn alive_renewal(window: Duration) -> Duration { - (window / 7).clamp(Duration::from_secs(3600), Duration::from_secs(24 * 3600)) + (window / 7).clamp(RENEWAL_MOST_OFTEN, Duration::from_secs(24 * 3600)) } +const RENEWAL_MOST_OFTEN: Duration = Duration::from_secs(3600); + +/// The shortest `--electorate-window`: seven renewals at most often, so a live node +/// renews within a seventh of it, as with any longer one. +pub(crate) const MIN_ELECTORATE_WINDOW: Duration = + Duration::from_secs(7 * RENEWAL_MOST_OFTEN.as_secs()); + /// Registers this node if it is ready and its entry is missing, keeps its alias as /// configured (set, changed or removed after a restart with another `--alias`) and its /// addresses as the transport gives them, and renews its `alive` stamp now and then |
