summaryrefslogtreecommitdiffstats
path: root/src/state.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-21 14:51:51 +0200
committertv <tv@krebsco.de>2026-10-21 14:51:51 +0200
commitd332830dfee1c6da4726cd69698f9edd18a33e0e (patch)
tree48d3dbc479902c2d56f1b5e4ab35484125ec1bac /src/state.rs
parent8891ebd88f87ff93c1efab51d0b9373f845a1dee (diff)
rename cluster to swarm everywhere!
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs106
1 files changed, 47 insertions, 59 deletions
diff --git a/src/state.rs b/src/state.rs
index ede5950..3925772 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
);
}
}
@@ -773,13 +761,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
}
@@ -790,12 +778,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 };
}
}
}