aboutsummaryrefslogtreecommitdiffstats
path: root/src/swarm/dissemination.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/swarm/dissemination.rs')
-rw-r--r--src/swarm/dissemination.rs51
1 files changed, 51 insertions, 0 deletions
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<Plan>;
+
+ /// `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<Plan>;
+
+ /// 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<u64>,
+ carried: bool,
+ authors: &[(String, Vec<ChangeHash>)],
+ );
+}