From 490234bbd44356da1cca0ad62b044e0cba70a226 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 24 Oct 2026 06:09:22 +0200 Subject: add swarm stats --- src/swarm/topology.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/swarm/topology.rs') diff --git a/src/swarm/topology.rs b/src/swarm/topology.rs index 8e25a2a..c5a02f1 100644 --- a/src/swarm/topology.rs +++ b/src/swarm/topology.rs @@ -48,6 +48,44 @@ pub(crate) fn is_full_mesh(state: &AppState) -> bool { .is_none_or(|view| view.full_mesh) } +/// The current view in numbers, once known. +#[derive(Debug, Clone, Copy)] +pub(crate) struct Summary { + /// Registered members, us included. + pub(crate) members: usize, + /// Members other than us not currently judged unreachable. + pub(crate) reachable: usize, + pub(crate) stable: usize, + pub(crate) neighbours: usize, + pub(crate) stable_neighbours: usize, + pub(crate) full_mesh: bool, +} + +pub(crate) fn summary(state: &AppState) -> Option { + let local = state.local_id(); + state + .neighbours + .read() + .unwrap_or_else(|poisoned| poisoned.into_inner()) + .as_ref() + .map(|view| Summary { + members: view.members.len(), + reachable: view + .members + .iter() + .filter(|m| m.as_str() != local && !view.unreachable.contains(*m)) + .count(), + stable: view.stable.len(), + neighbours: view.neighbours.len(), + stable_neighbours: view + .neighbours + .iter() + .filter(|m| view.stable.contains(*m)) + .count(), + full_mesh: view.full_mesh, + }) +} + /// Whether we initiate contact with `peer`: HELLOs, keepalives, dormancy checks, sync /// openings. Everyone is a neighbour until the view is known (while joining, or before /// any member registered), so joining works as in a full mesh. We always *answer* -- cgit v1.3.1