summaryrefslogtreecommitdiffstats
path: root/src/state.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-20 02:25:54 +0200
committertv <tv@krebsco.de>2026-10-20 02:25:54 +0200
commit6ef01932cc08bdb1a514d30ab6fb3f131f38f4dc (patch)
treeffd79831f0d4510cf6606cfbe5c79e0f9ccaa55b /src/state.rs
parent11a8ec06429b639e9fefec85b72a48451acad456 (diff)
fix catch-up / compaction in general
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs20
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)
})