1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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>)],
);
}
|