diff options
Diffstat (limited to 'src/state.rs')
| -rw-r--r-- | src/state.rs | 106 |
1 files changed, 47 insertions, 59 deletions
diff --git a/src/state.rs b/src/state.rs index 81a3e6a..736f55b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -20,13 +20,9 @@ use crate::transport::firewall::Firewall; #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum NodeLifecycle { - // TODO maybe rename discovered_cluster_id to cluster_id if that doesn't impair readability. - Joining { - discovered_cluster_id: Option<String>, - }, - Ready { - cluster_id: String, - }, + // TODO maybe rename discovered_swarm_id to swarm_id if that doesn't impair readability. + Joining { discovered_swarm_id: Option<String> }, + Ready { swarm_id: String }, } #[derive(Debug, Clone, Default, PartialEq, Eq)] @@ -34,7 +30,7 @@ pub(crate) enum PeerMembership { #[default] Unknown, Member { - cluster_id: String, + swarm_id: String, }, } @@ -75,7 +71,7 @@ pub(crate) struct PeerState { pub(crate) sync_state: sync::State, pub(crate) hello_state: HelloState, - /// The peer sent HELLO; we still owe it a HELLO_REPLY (e.g. we had no cluster ID yet, + /// The peer sent HELLO; we still owe it a HELLO_REPLY (e.g. we had no swarm ID yet, /// or sending failed). pub(crate) reply_owed: bool, @@ -302,7 +298,7 @@ impl PeerState { } /// Heard from recently. A returning node counts as alive from its first message, - /// before the handshake finishes, so a cluster-wide forget can't make it flap. + /// before the handshake finishes, so a swarm-wide forget can't make it flap. pub(crate) fn is_alive(&self, timing: &Timing, now: Instant) -> bool { self.liveness == Liveness::Active && self @@ -324,9 +320,9 @@ impl Timing { // Environment | Keepalive | Notes // --------------------------------------------+-----------+------------------------------------------------------------ // Test harness | 1-2 s | Dormancy after about 4–8 s and healing within seconds keep tests short. - // LAN or small cluster (up to ~50 nodes) | 15-30 s | Under 3.5 messages/s per node at 50 nodes and 30 s. Current setting. + // LAN or small swarm (up to ~50 nodes) | 15-30 s | Under 3.5 messages/s per node at 50 nodes and 30 s. Current setting. // WAN, mobile or metered links, or 100+ nodes | 60-120 s | At 100 nodes and 30 s it’s about 6–7 messages/s per node. Fine, but rarely worth it on battery or metered links. - // Several hundred nodes or more | - | The full mesh becomes the problem in itself, not the interval. Message counts grow O(N²) across the cluster, which calls for partial views (SWIM-style random probing and syncing with a subset of peers). + // Several hundred nodes or more | - | The full mesh becomes the problem in itself, not the interval. Message counts grow O(N²) across the swarm, which calls for partial views (SWIM-style random probing and syncing with a subset of peers). pub(crate) fn from_keepalive(keepalive: Duration) -> Self { Self { keepalive, @@ -348,8 +344,8 @@ pub(crate) struct AppState { pub(crate) lifecycle: Arc<RwLock<NodeLifecycle>>, - // Serializes cluster-ID establishment, peer membership, and readiness transitions. - //[concurrent]cluster_validation: Arc<Mutex<()>>, + // Serializes swarm-ID establishment, peer membership, and readiness transitions. + //[concurrent]swarm_validation: Arc<Mutex<()>>, pub(crate) peer_states: Arc<RwLock<HashMap<String, Arc<Mutex<PeerState>>>>>, pub(crate) transport: Arc<dyn transport::Transport>, pub(crate) firewall: Arc<Firewall>, @@ -388,94 +384,86 @@ impl AppState { matches!(*self.lifecycle.read().await, NodeLifecycle::Ready { .. }) } - pub(crate) async fn cluster_id(&self) -> Option<String> { + pub(crate) async fn swarm_id(&self) -> Option<String> { match &*self.lifecycle.read().await { - NodeLifecycle::Ready { cluster_id } => Some(cluster_id.clone()), + NodeLifecycle::Ready { swarm_id } => Some(swarm_id.clone()), NodeLifecycle::Joining { - discovered_cluster_id, - } => discovered_cluster_id.clone(), + discovered_swarm_id, + } => discovered_swarm_id.clone(), } } - // Record the expected cluster without making the node Ready. Bootstrap owns readiness. - pub(crate) async fn set_expected_cluster_id(&self, cluster_id: String) -> Result<()> { - //[concurrent]let _guard = self.cluster_validation.lock().await; + // Record the expected swarm without making the node Ready. Bootstrap owns readiness. + pub(crate) async fn set_expected_swarm_id(&self, swarm_id: String) -> Result<()> { + //[concurrent]let _guard = self.swarm_validation.lock().await; let mut lifecycle = self.lifecycle.write().await; match &*lifecycle { NodeLifecycle::Joining { - discovered_cluster_id: Some(existing), - } if existing != &cluster_id => { + discovered_swarm_id: Some(existing), + } if existing != &swarm_id => { bail!( - "Conflicting expected cluster IDs: expected {}, received {}", + "Conflicting expected swarm IDs: expected {}, received {}", existing, - cluster_id + swarm_id ); } NodeLifecycle::Joining { - discovered_cluster_id: None, + discovered_swarm_id: None, } => { let old_lifecycle = lifecycle.clone(); *lifecycle = NodeLifecycle::Joining { - discovered_cluster_id: Some(cluster_id), + discovered_swarm_id: Some(swarm_id), }; debug!("Node transitioned from {old_lifecycle:?} {lifecycle:?}"); Ok(()) } NodeLifecycle::Joining { - discovered_cluster_id: Some(_), + discovered_swarm_id: Some(_), } => { warn!("Node already Joining with the same identity"); Ok(()) } - NodeLifecycle::Ready { - cluster_id: existing, - } if existing == &cluster_id => { + NodeLifecycle::Ready { swarm_id: existing } if existing == &swarm_id => { warn!("Node already Ready with the same identity"); Ok(()) } - NodeLifecycle::Ready { - cluster_id: existing, - } => { + NodeLifecycle::Ready { swarm_id: existing } => { bail!( - "Cannot change established cluster ID: existing {}, received {}", + "Cannot change established swarm ID: existing {}, received {}", existing, - cluster_id + swarm_id ); } } } // Only bootstrap should call this, after validating document metadata. - pub(crate) async fn mark_ready(&self, cluster_id: String) -> Result<()> { - //[concurrent]let _guard = self.cluster_validation.lock().await; + pub(crate) async fn mark_ready(&self, swarm_id: String) -> Result<()> { + //[concurrent]let _guard = self.swarm_validation.lock().await; let mut lifecycle = self.lifecycle.write().await; match &*lifecycle { NodeLifecycle::Joining { - discovered_cluster_id: Some(expected), - } if expected != &cluster_id => { + discovered_swarm_id: Some(expected), + } if expected != &swarm_id => { bail!( - "Cannot mark node ready: expected cluster {}, received {}", + "Cannot mark node ready: expected swarm {}, received {}", expected, - cluster_id + swarm_id ); } NodeLifecycle::Joining { .. } => { let old_lifecycle = lifecycle.clone(); - *lifecycle = NodeLifecycle::Ready { cluster_id }; + *lifecycle = NodeLifecycle::Ready { swarm_id }; debug!("Node transitioned from {old_lifecycle:?} {lifecycle:?}"); } - NodeLifecycle::Ready { - cluster_id: existing, - } if existing == &cluster_id => { + NodeLifecycle::Ready { swarm_id: existing } if existing == &swarm_id => { debug!("Node already ready with the same identity"); } - NodeLifecycle::Ready { - cluster_id: existing, - } => { + NodeLifecycle::Ready { swarm_id: existing } => { bail!( - "Cannot change established cluster ID: existing {}, received {}", + "Cannot change established swarm ID: existing {}, received {}", existing, - cluster_id + swarm_id ); } } @@ -774,13 +762,13 @@ impl Host for AppState { let state = self.clone(); async move { let mut lifecycle = state.lifecycle.write().await; - let NodeLifecycle::Ready { cluster_id } = &*lifecycle else { + let NodeLifecycle::Ready { swarm_id } = &*lifecycle else { return false; }; - let cluster_id = cluster_id.clone(); - debug!(cluster_id = %cluster_id, "Node suspended (rejoining)"); + let swarm_id = swarm_id.clone(); + debug!(swarm_id = %swarm_id, "Node suspended (rejoining)"); *lifecycle = NodeLifecycle::Joining { - discovered_cluster_id: Some(cluster_id), + discovered_swarm_id: Some(swarm_id), }; true } @@ -791,12 +779,12 @@ impl Host for AppState { async move { let mut lifecycle = state.lifecycle.write().await; if let NodeLifecycle::Joining { - discovered_cluster_id: Some(cluster_id), + discovered_swarm_id: Some(swarm_id), } = &*lifecycle { - let cluster_id = cluster_id.clone(); - debug!(cluster_id = %cluster_id, "Node resumed"); - *lifecycle = NodeLifecycle::Ready { cluster_id }; + let swarm_id = swarm_id.clone(); + debug!(swarm_id = %swarm_id, "Node resumed"); + *lifecycle = NodeLifecycle::Ready { swarm_id }; } } } |
