aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/openapi.yaml2
-rw-r--r--docs/peers.md6
-rw-r--r--src/api/peers.rs4
-rw-r--r--src/simtest/reach.rs2
-rw-r--r--src/swarm/reach.rs24
-rw-r--r--src/swarm/tree.rs2
6 files changed, 18 insertions, 22 deletions
diff --git a/docs/openapi.yaml b/docs/openapi.yaml
index b7cd3ab..03f75d9 100644
--- a/docs/openapi.yaml
+++ b/docs/openapi.yaml
@@ -1638,7 +1638,7 @@ components:
type: [array, 'null']
items:
type: string
- description: The members it said it reaches, by node ID (those in our member list); null before it said so, or once that is stale.
+ description: The members it said it reaches, by node ID (those in our member list); null before it said so since its session began (handshake, or back from dormant).
traffic:
$ref: '#/components/schemas/Traffic'
incidents:
diff --git a/docs/peers.md b/docs/peers.md
index 939f318..377d8aa 100644
--- a/docs/peers.md
+++ b/docs/peers.md
@@ -302,8 +302,10 @@ has an active session with (handshake done, neither dormant nor unreachable), ea
an 8-byte key (the hash its pair scores come from), in its keepalive STATUSes and
their replies, and within 5 s when it changed; not in announcements of heads, which go
often. So every node knows its 2-hop neighbourhood as measured, not as the member list
-says, for as long as it is fresh (two STATUS refreshes and a keepalive: 7 minutes with
-the default keepalive), and nothing goes into the document. `GET /peers` shows it
+says, for as long as each neighbour's session lasts (one that goes dormant or starts
+anew says it again), and nothing goes into the document. Not for a set time: while a
+pair exchanges changes it sends no keepalives, and so no STATUS, however long the
+writes go on. `GET /peers` shows it
(`localReaches`, and `reaches` per peer).
A writer's changes pass on along its tree ([`swarm/tree.rs`](../src/swarm/tree.rs)), the same on every node:
diff --git a/src/api/peers.rs b/src/api/peers.rs
index cd70f7d..6662a55 100644
--- a/src/api/peers.rs
+++ b/src/api/peers.rs
@@ -61,7 +61,7 @@ pub(crate) struct PeerStatus {
/// We keep it alive and sync with it on our own; other peers we only answer.
pub(crate) neighbour: bool,
/// The members it said it reaches (`swarm::reach`), by node ID, while that holds;
- /// absent before it said so, or once it is stale. Keys of members not in our member
+ /// absent before it said so in this session. Keys of members not in our member
/// list are left out.
pub(crate) reaches: Option<Vec<String>>,
/// Messages and payload bytes exchanged with it, by kind, since we started (or
@@ -187,7 +187,7 @@ pub(crate) async fn peer_list(state: &AppState) -> PeerListResponse {
same_epoch: ps.epoch.map(|epoch| epoch == local_epoch),
heads: ps.reported_heads,
neighbour,
- reaches: crate::swarm::reach::of(&state, ps.reaches.as_ref()).map(&named),
+ reaches: crate::swarm::reach::of(ps.reaches.as_ref()).map(&named),
traffic,
incidents: ps.incidents,
sync_throughput,
diff --git a/src/simtest/reach.rs b/src/simtest/reach.rs
index 20f770c..f501aef 100644
--- a/src/simtest/reach.rs
+++ b/src/simtest/reach.rs
@@ -21,7 +21,7 @@ async fn heard(node: &AppState, neighbour: &AppState, member: &AppState) -> bool
return false;
};
let said = peer_state.lock().await.reaches.clone();
- reach::of(node, said.as_ref())
+ reach::of(said.as_ref())
.is_some_and(|keys| keys.contains(&topology::pair_key(member.local_id())))
}
diff --git a/src/swarm/reach.rs b/src/swarm/reach.rs
index 17b189d..901b47c 100644
--- a/src/swarm/reach.rs
+++ b/src/swarm/reach.rs
@@ -8,9 +8,11 @@
//! STATUS_REPLY, and soon (the peer worker looks every 5 s) to every neighbour when it
//! changed,
//! but not in announcements of heads, which go often. So every node knows whom its
-//! neighbours reach, as of their latest STATUS: for as long as that is fresh
-//! (`held_for`), then not, until the next. Nothing goes into the document, and nobody
-//! knows more than two hops out.
+//! neighbours 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.
//!
//! 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,
@@ -20,7 +22,6 @@
//! nothing but in a full mesh.
use std::collections::HashMap;
-use std::time::Duration;
use tokio::time::Instant;
use tracing::debug;
@@ -96,17 +97,10 @@ async fn tell(state: &AppState, peer: &str) -> anyhow::Result<()> {
announce_heads(state, peer, true).await
}
-/// How long what a neighbour said it reaches holds: past two of its regular STATUSes,
-/// each of which says it again.
-pub(crate) fn held_for(state: &AppState) -> Duration {
- state.timing.status_refresh * 2 + state.timing.keepalive
-}
-
-/// The members `peer` reaches, as it last said, while that holds (`held_for`); by
-/// pair key.
-pub(crate) fn of(state: &AppState, said: Option<&(Instant, Vec<u64>)>) -> Option<Vec<u64>> {
- said.filter(|(at, _)| at.elapsed() < held_for(state))
- .map(|(_, reaches)| reaches.clone())
+/// The members a peer reaches, as it last said in this session (`said`, kept with its
+/// state, cleared when the session ends: `PeerState::reset_sync`); by pair key.
+pub(crate) fn of(said: Option<&(Instant, Vec<u64>)>) -> Option<Vec<u64>> {
+ said.map(|(_, reaches)| reaches.clone())
}
/// The members of our member list by pair key, to name what neighbours say they reach.
diff --git a/src/swarm/tree.rs b/src/swarm/tree.rs
index ee46271..8031a69 100644
--- a/src/swarm/tree.rs
+++ b/src/swarm/tree.rs
@@ -125,7 +125,7 @@ pub(crate) async fn plan(state: &AppState, writer: u64) -> Option<Plan> {
reaches.insert(me, reach::published(state));
for member in graph.get(me).into_iter().flatten() {
if let Some(peer_state) = state.get_peer_state(member).await
- && let Some(keys) = reach::of(state, peer_state.lock().await.reaches.as_ref())
+ && let Some(keys) = reach::of(peer_state.lock().await.reaches.as_ref())
{
reaches.insert(member.as_str(), keys);
}