diff options
Diffstat (limited to 'src/swarm/reach.rs')
| -rw-r--r-- | src/swarm/reach.rs | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/swarm/reach.rs b/src/swarm/reach.rs index d4949ef..760bcb5 100644 --- a/src/swarm/reach.rs +++ b/src/swarm/reach.rs @@ -15,8 +15,9 @@ //! reach, as of their latest STATUS, for as long as the session lasts (a //! neighbour that goes dormant, or starts anew, says it again). Not for a set time: //! while a pair exchanges changes it sends no keepalives, and so no STATUS, for as -//! long as the writes go on. Nothing goes into the document, and nobody knows more than -//! two hops out. +//! long as the writes go on. Nothing of it goes into the document (but where a link +//! stays down for a while: `swarm::working_links`), and nobody knows more than two hops +//! out. //! //! What it is for: passing changes on around links that don't work, and to exactly the //! members the sender doesn't reach; a member a neighbour reaches is one worth trying, @@ -25,7 +26,7 @@ //! every neighbour would be one (13.7 of 13.7 at 250 members and more), saving next to //! nothing but in a full mesh. -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use tokio::time::Instant; use tracing::debug; @@ -77,18 +78,11 @@ pub(crate) struct Reach { /// told before (`before`, by pair key: `rtt::bucket`). async fn measure(state: &AppState, before: &HashMap<u64, u8>) -> (Vec<u64>, Vec<u8>) { let now = Instant::now(); - let mut reached = Vec::new(); - for (peer, peer_state) in state.peers_snapshot().await { - let peer_state = peer_state.lock().await; - if peer_state.hello_state == HelloState::Established - && !peer_state.liveness.is_dormant() - && !peer_state.is_unreachable() - && !peer_state.answer_overdue(now) - && matches!(peer_state.standing, Standing::Member { .. }) - { - reached.push((topology::pair_key(&peer), peer)); - } - } + let mut reached: Vec<(u64, String)> = reached_members(state, now) + .await + .into_iter() + .map(|peer| (topology::pair_key(&peer), peer)) + .collect(); reached.sort_unstable(); let rtts = state.lock_rtt(); let round_trips = reached @@ -104,6 +98,24 @@ async fn measure(state: &AppState, before: &HashMap<u64, u8>) -> (Vec<u64>, Vec< ) } +/// The members we reach now: those with an active session (handshake done, neither +/// dormant nor unreachable) that answer. +pub(crate) async fn reached_members(state: &AppState, now: Instant) -> BTreeSet<String> { + let mut reached = BTreeSet::new(); + for (peer, peer_state) in state.peers_snapshot().await { + let peer_state = peer_state.lock().await; + if peer_state.hello_state == HelloState::Established + && !peer_state.liveness.is_dormant() + && !peer_state.is_unreachable() + && !peer_state.answer_overdue(now) + && matches!(peer_state.standing, Standing::Member { .. }) + { + reached.insert(peer); + } + } + reached +} + /// Whom we reach, as we tell it (`Status::reaches`); empty until first measured. pub(crate) fn published(state: &AppState) -> Vec<u64> { published_with_round_trips(state).0 |
