From 8a134df62167a85fa083ccf480a939fd654e2419 Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 6 Nov 2026 16:35:02 +0100 Subject: dissemination trait --- src/swarm/dissemination.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/swarm/dissemination.rs (limited to 'src/swarm/dissemination.rs') diff --git a/src/swarm/dissemination.rs b/src/swarm/dissemination.rs new file mode 100644 index 0000000..1d92b06 --- /dev/null +++ b/src/swarm/dissemination.rs @@ -0,0 +1,51 @@ +//! How a change reaches every member: whom a node sends a writer's changes to at once, +//! and whom it leaves to the announcement rounds (`swarm::relay`, which repair what it +//! misses: announcements, pulls, the slow round). Writers' trees (`swarm::tree`) are +//! one way; others can be tried against them in the benchmark (`docs/future-work.md`, +//! Swappable topology and dissemination). One per swarm: a node's part in passing a +//! change on is worked out by itself and by its neighbours, and must agree. +//! +//! What every way keeps: the base underneath, pairs of neighbours syncing with +//! Automerge, which delivers everything in the end; a way only decides whom to push to +//! first, and so how soon. + +use async_trait::async_trait; + +use crate::document::ChangeHash; +use crate::state::AppState; +use crate::swarm::tree::Plan; + +#[async_trait] +pub(crate) trait Dissemination: Send + Sync + 'static { + /// Its name (in logs, and once chosen by the swarm, in the document). + fn name(&self) -> &'static str; + + /// Our part in passing on `writer`'s changes (by its pair key, `topology::pair_key`): + /// whom we send them to at once, and how the announcement rounds treat our other + /// neighbours (`Plan`). None: we have no part, and announcements do it all. + async fn plan(&self, state: &AppState, writer: u64) -> Option; + + /// `writer`'s `changes` came from `from` (none: we had them already, and they came + /// as the writer's now): passed on at once to those we send them to, the others + /// counted as having them where they get them elsewhere. Returns our part, as + /// `plan`. + async fn forward( + &self, + state: &AppState, + writer: u64, + from: &str, + changes: &[ChangeHash], + ) -> Option; + + /// What a sync message from `peer` says about how well this works (`/admin/stats`): + /// whether it came as `writer`'s and `carried` changes, and the new changes it + /// brought, by author. Not while catching up. + async fn note_arrival( + &self, + state: &AppState, + peer: &str, + writer: Option, + carried: bool, + authors: &[(String, Vec)], + ); +} -- cgit v1.3.1