diff options
| author | tv <tv@krebsco.de> | 2026-10-30 17:39:05 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-30 17:39:05 +0100 |
| commit | b224eee76a9314992ec7a83321803e11a0b0b37f (patch) | |
| tree | c5ec81fa50534626847242bcd451642b0efdf5bd | |
| parent | 0bb7a35141c12a58001b481851d33291d2a6ec98 (diff) | |
introduce intended graph
| -rw-r--r-- | src/swarm/topology.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/swarm/topology.rs b/src/swarm/topology.rs index 3731036..063fc41 100644 --- a/src/swarm/topology.rs +++ b/src/swarm/topology.rs @@ -119,6 +119,41 @@ pub(crate) fn is_neighbour(state: &AppState, peer: &str) -> bool { } } +/// Every member's neighbours as the member list makes them, as this node sees it (whom +/// it can reach, who is stable): the graph each node computes its own part of. Ours as +/// they are (with members that only connect out, or aren't listed yet). For a map of +/// the swarm (the dashboard); None until the view is known. A link exists if either end +/// chose it: draw one if either lists the other. About `members²` work: compute it when +/// the member list may have changed, not on every look. +#[cfg_attr(not(feature = "dashboard"), allow(dead_code))] +pub(crate) fn intended_graph(state: &AppState) -> Option<BTreeMap<String, BTreeSet<String>>> { + let view = state.neighbours.read_or_recover(); + let view = view.as_ref()?; + let unreachable = |member: &str| view.unreachable.contains(member); + let stable = |member: &str| view.stable.contains(member); + let graph = view + .members + .iter() + .map(|member| { + let neighbours = if member == state.local_id() { + view.neighbours.clone() + } else { + let own = view.transports.get(member).cloned().unwrap_or_default(); + neighbours_across( + &view.transports, + member, + &own, + view.k, + &unreachable, + &stable, + ) + }; + (member.clone(), neighbours) + }) + .collect(); + Some(graph) +} + /// How the neighbours changed. pub(crate) struct NeighbourChange { pub(crate) added: Vec<String>, |
