aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/measurements.md2
-rw-r--r--src/simtest/relay.rs9
-rw-r--r--src/swarm/relay.rs11
3 files changed, 12 insertions, 10 deletions
diff --git a/docs/measurements.md b/docs/measurements.md
index 086cd17..9cdc265 100644
--- a/docs/measurements.md
+++ b/docs/measurements.md
@@ -80,7 +80,7 @@ or caught up over many small messages.
| `sync.lastFromNeighbourSecs` | `last_sync_from_neighbour_seconds` | Since a sync message from any neighbour was applied. Growing without bound while others write: the node is cut off from the swarm's changes. |
| `sync.divergedPeers` | `diverged_peers` | Peers whose heads differ from ours with no sync message in between. |
| `sync.largestReceivedBytes` | `largest_sync_received_bytes` | The largest sync message received since start. Larger transfers come as deltas (blobs of 16 chunks or more, [`peers.md`](peers.md)), so this stays below 16 × `--blob-chunk` from nodes of this version. |
-| `relay.announceRounds` | `announce_rounds_total` | Announcement rounds: our new heads to the neighbours after applying their changes (partial mesh only). |
+| `relay.announceRounds` | `announce_rounds_total` | Announcement rounds: our new heads to the neighbours after applying their changes (the quick round to those writers' trees leave out, or to all for changes no tree carries, and the slow round to the others; [`peers.md`](peers.md)). |
| `relay.pulls` | `pulls_total` | Pulls of changes we lacked from a neighbour that announced them. |
| `relay.pullsQueued` | `pulls_queued_total` | Announcements of heads we lacked that waited for the pull in progress. Many compared with `pulls`: changes arrive from several sides at once. |
| `relay.treeForwards` | `tree_forwards_total` | Changes passed on along writers' trees ([`peers.md`](peers.md)): a sync message per child, at once, instead of an announcement and a pull. |
diff --git a/src/simtest/relay.rs b/src/simtest/relay.rs
index da1ce0a..0b7c739 100644
--- a/src/simtest/relay.rs
+++ b/src/simtest/relay.rs
@@ -15,10 +15,11 @@ const SOON: Duration = Duration::from_secs(30);
/// a on `sim` alone, c on `sim2` alone, b on both; a full mesh at each (every member
/// it reaches is its neighbour), so a pushes its write to b alone, and b, which only
-/// received it, must announce it to c. With a long keepalive, the regular STATUS (every
-/// third keepalive, 15 s) can't be what brings it: c has it within a second (an
-/// announcement waits 200 ms, then c pulls). Without the announcement, a STATUS that
-/// happens to fall into that second would pass it too, once in about 15 runs.
+/// received it, must pass it on to c: along a's tree at once (b is c's parent), else by
+/// announcement 200 to 400 ms later and a pull. With a long keepalive, the regular
+/// STATUS (every third keepalive, 15 s) can't be what brings it: c has it within a
+/// second. Without either, a STATUS that happens to fall into that second would pass it
+/// too, once in about 15 runs.
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn changes_reach_members_the_writer_cant_reach_at_once() {
let keepalive = Duration::from_secs(5);
diff --git a/src/swarm/relay.rs b/src/swarm/relay.rs
index f79c601..29da2eb 100644
--- a/src/swarm/relay.rs
+++ b/src/swarm/relay.rs
@@ -1,14 +1,15 @@
-//! Passing changes on in a partial mesh (`swarm::topology`).
+//! Passing changes on (`swarm::topology`): along writers' trees (`swarm::tree`), and by
+//! announcement and pull where they don't reach.
//!
//! A node pushes its own changes to its neighbours, but nothing it receives goes any
-//! further by itself. So after applying changes from one neighbour, a node *announces*
+//! further by itself but along a writer's tree. So after applying changes from one
+//! neighbour, a node *announces*
//! its new heads to its other neighbours with a STATUS (heads, about 100 bytes, not the
//! changes; no keepalive, and answered only by a neighbour whose heads differ). A
//! neighbour that sees heads it lacks *pulls*: it enters the
//! announced heads as the peer's heads in its sync state, Automerge asks for what's
-//! missing (`need`), and the announcer answers with exactly those changes. Each node
-//! receives a change about once; the rest is announcements. Regular keepalives work the
-//! same way, so any gap is noticed within a keepalive interval.
+//! missing (`need`), and the announcer answers with exactly those changes. Regular
+//! keepalives work the same way, so any gap is noticed within a keepalive interval.
//!
//! Announcements are coalesced: the first applied change schedules one announcement
//! round `ANNOUNCE_DELAY` later, and every change applied until then rides along. A