diff options
Diffstat (limited to 'src/swarm/topology.rs')
| -rw-r--r-- | src/swarm/topology.rs | 38 |
1 files changed, 38 insertions, 0 deletions
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<Summary> { + 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* |
