aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-06 04:32:33 +0100
committertv <tv@krebsco.de>2026-11-06 04:32:33 +0100
commit8a37ace76af52a3497213d5aa5531c85726e1ef6 (patch)
tree27ab40363dfa46f5ba95c73a1bcd1dae6f7919c6
parentc85e4efec5bf8c5d83401816b6de4f46fbedd99e (diff)
links member from the view
-rw-r--r--src/swarm/links.rs15
-rw-r--r--src/swarm/topology/mod.rs10
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 {