diff options
Diffstat (limited to 'src/state.rs')
| -rw-r--r-- | src/state.rs | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/state.rs b/src/state.rs index 4c7282f..f9da5e0 100644 --- a/src/state.rs +++ b/src/state.rs @@ -531,6 +531,20 @@ impl AppState { // Sync states were reset under the document lock by the swap itself. self.publish_change(); + // Tell peers about the new epoch now instead of with the next keepalive (up to a + // keepalive interval later): sync with peers already on it resumes right away, + // and peers that never saw the commit start catching up. + let keepalive = crate::peer::local_keepalive(self).await; + for (id, _) in &peers { + if let Err(error) = self + .transport + .send_message(id, &transport::ParsedMessage::Ping(keepalive.clone())) + .await + { + debug!(peer = %id, error = %format!("{error:#}"), "Epoch announcement failed"); + } + } + for (id, _) in peers { let _ = self.sync_events.send(SyncEvent::PeerNeedsSync(id)); } @@ -669,8 +683,12 @@ impl Host for AppState { // 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.) + let now = Instant::now(); for peer in state.peer_states.blocking_read().values() { - peer.blocking_lock().reset_sync(); + let mut peer = peer.blocking_lock(); + peer.reset_sync(); + // A fresh start, not an idle sync: no heal re-handshake for it. + peer.last_sync_rx = Some(now); } Ok(old_doc) }) |
