diff options
| author | tv <tv@krebsco.de> | 2026-10-24 04:23:38 +0200 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-24 04:47:07 +0200 |
| commit | 6fa188610ce0959e0b61ecaf63f5babf826d2071 (patch) | |
| tree | a955457989abfe4832fe0213b5054d3b34c98ab1 /src/swarm/topology.rs | |
| parent | c2468964b11bd3606f03375c370fd181a1723113 (diff) | |
pull missing changes
Nodes push changes to their neighbours but don't relay them directly.
In a partial mesh, nodes can learn about missing changes via keepalive
messages and can pull them from their neighbours.
Diffstat (limited to 'src/swarm/topology.rs')
| -rw-r--r-- | src/swarm/topology.rs | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/swarm/topology.rs b/src/swarm/topology.rs index b5880cf..dddf81b 100644 --- a/src/swarm/topology.rs +++ b/src/swarm/topology.rs @@ -33,6 +33,18 @@ pub(crate) struct NeighbourView { k: usize, unreachable: BTreeSet<String>, neighbours: BTreeSet<String>, + /// Every reachable member is a neighbour. + full_mesh: bool, +} + +/// Whether every reachable member is our neighbour (also while the view is unknown). +pub(crate) fn is_full_mesh(state: &AppState) -> bool { + state + .neighbours + .read() + .unwrap_or_else(|poisoned| poisoned.into_inner()) + .as_ref() + .is_none_or(|view| view.full_mesh) } /// Whether we initiate contact with `peer`: HELLOs, keepalives, dormancy checks, sync @@ -113,10 +125,15 @@ pub(crate) async fn refresh(state: &AppState) -> Option<NeighbourChange> { removed = change.removed.len(), "Neighbours computed from the member list" ); + let reachable_others = current + .iter() + .filter(|m| m.as_str() != state.local_id() && !unreachable.contains(*m)) + .count(); *state .neighbours .write() .unwrap_or_else(|poisoned| poisoned.into_inner()) = Some(NeighbourView { + full_mesh: computed.len() >= reachable_others, members: current, k, unreachable, |
