diff options
| -rw-r--r-- | src/swarm/links.rs | 15 | ||||
| -rw-r--r-- | src/swarm/topology/mod.rs | 10 |
2 files changed, 20 insertions, 5 deletions
diff --git a/src/swarm/links.rs b/src/swarm/links.rs index 2d9071b..ea5564e 100644 --- a/src/swarm/links.rs +++ b/src/swarm/links.rs @@ -616,11 +616,16 @@ pub(crate) async fn unsubscribe(state: &AppState, member: &str) { /// A LINKS from `peer`: answered if it's a member, and not answered lately. pub(crate) async fn answer(state: &AppState, peer: &str, request: LinksRequest) { - let member = { - let replica = state.doc.read().await; - members::members(&replica.doc) - .iter() - .any(|member| member == peer) + // From the neighbours' view, kept as the member list changes: no document read per + // request. + let member = match crate::swarm::topology::listed(state, peer) { + Some(listed) => listed, + None => { + let replica = state.doc.read().await; + members::members(&replica.doc) + .iter() + .any(|member| member == peer) + } }; if !member { debug!(peer = %peer, "Not answering LINKS from a peer that isn't a member"); diff --git a/src/swarm/topology/mod.rs b/src/swarm/topology/mod.rs index 179cf83..b001809 100644 --- a/src/swarm/topology/mod.rs +++ b/src/swarm/topology/mod.rs @@ -100,6 +100,16 @@ pub(crate) fn member_list_graph( }))) } +/// Whether `peer` is in the member list, as the view was last computed from it; None +/// while the view isn't known. +pub(crate) fn listed(state: &AppState, peer: &str) -> Option<bool> { + state + .neighbours + .read_or_recover() + .as_ref() + .map(|view| view.members.iter().any(|member| member == peer)) +} + /// Whether the neighbours are computed from the member list yet (before, everyone /// counts as a neighbour). pub(crate) fn view_known(state: &AppState) -> bool { |
