diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/node.rs | 2 | ||||
| -rw-r--r-- | src/state/host.rs | 6 | ||||
| -rw-r--r-- | src/state/mod.rs | 9 | ||||
| -rw-r--r-- | src/swarm/peer/epoch.rs | 3 |
4 files changed, 9 insertions, 11 deletions
diff --git a/src/node.rs b/src/node.rs index 8224c7a..f6bdbb3 100644 --- a/src/node.rs +++ b/src/node.rs @@ -69,7 +69,6 @@ impl Node { let (sync_tx, sync_rx) = mpsc::unbounded_channel(); let (change_tx, _) = watch::channel(0_u64); let (change_events, _) = broadcast::channel(256); - let (epoch_tx, _) = watch::channel(config.initial_epoch); let firewall = Arc::new(Firewall::default()); let traffic = Arc::new(Traffic::default()); let initial_actor = crate::document::actor(&config.initial_doc); @@ -88,7 +87,6 @@ impl Node { let stamp = replica.stamps(); let state = AppState { doc: Arc::new(crate::document::lock::DocumentLock::new(replica)), - epoch_tx, stamp, lifecycle: Arc::new(RwLock::new(NodeLifecycle::Joining { discovered_swarm_id: None, diff --git a/src/state/host.rs b/src/state/host.rs index 6bb9d3b..7c3e165 100644 --- a/src/state/host.rs +++ b/src/state/host.rs @@ -283,10 +283,10 @@ impl Host for AppState { replica.epoch = epoch; replica.epoch_seq += 1; replica.writable = writable; + // Publishes the epoch with the heads (`Replica::stamps`), under the + // same lock, so it never disagrees with the document for anyone + // holding the lock. replica.refresh_heads(); - // Updated under the same lock, so the cached epoch never disagrees - // with the document for anyone holding the lock. - state.epoch_tx.send_replace(epoch); // Reset every peer's sync state before the lock is released, so no // message is generated from or applied to a state that describes the // old document. (Lock order doc -> peer, as in sync generation.) diff --git a/src/state/mod.rs b/src/state/mod.rs index 9ee08b7..5e4a4d3 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -59,10 +59,9 @@ pub(crate) struct AppState { /// The document and its epoch. Derefs to `Document`. pub(crate) doc: Arc<DocumentLock>, - /// Copy of `doc.epoch` for cheap, lock-free reads (handshakes, keepalives, /peers). - /// Only ever changed while holding `doc`'s write lock, together with `doc.epoch`. - pub(crate) epoch_tx: watch::Sender<Epoch>, - /// `doc`'s epoch label and heads, readable without its lock (`Replica::stamps`). + /// `doc`'s epoch label and heads, readable without its lock (`Replica::stamps`): + /// for cheap reads (handshakes, keepalives, /peers). Only ever changed while holding + /// `doc`'s write lock, together with `doc.epoch`. pub(crate) stamp: watch::Receiver<Stamp>, pub(crate) lifecycle: Arc<RwLock<NodeLifecycle>>, @@ -231,7 +230,7 @@ impl AppState { /// The local epoch. Code that labels or applies sync messages must use the epoch /// of the locked `Replica` instead, so label and document can't disagree. pub(crate) fn local_epoch(&self) -> Epoch { - *self.epoch_tx.borrow() + self.stamp.borrow().epoch } /// The local epoch and `Replica::epoch_seq`, read together, without waiting for the diff --git a/src/swarm/peer/epoch.rs b/src/swarm/peer/epoch.rs index d97db0f..d00a903 100644 --- a/src/swarm/peer/epoch.rs +++ b/src/swarm/peer/epoch.rs @@ -13,7 +13,8 @@ use crate::transport; /// /// `seq` is the peer's `epoch_seq` with it. A message with a lower one than we have was /// sent before the peer's last epoch change and delivered late: its epoch isn't -/// recorded, so it can't flip our view of the peer back. The count starts over when the +/// recorded, so it can't flip our view of the peer back. The message itself still +/// counts: if its epoch is ours, its sync is applied (it is data of our epoch). The count starts over when the /// peer restarts, which its HELLO or HELLO_REPLY tells by a new run (`run`). pub(super) async fn observe_peer_epoch( state: &AppState, |
