From 8d70536fd267e7ee730c390b6b47c03ddbef7df9 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 26 Oct 2026 18:51:01 +0100 Subject: read stamps sync and lock free --- src/state/mod.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/state/mod.rs') diff --git a/src/state/mod.rs b/src/state/mod.rs index a51339c..962d62a 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -29,7 +29,7 @@ use tokio::sync::{Mutex, RwLock, broadcast, mpsc, watch}; use tokio::time::Instant; use tracing::{debug, error, warn}; -use crate::document::replica::{Epoch, Replica}; +use crate::document::replica::{Epoch, Replica, Stamp}; use crate::locks::MutexExt; use crate::remake::{Host, RemakeState}; use crate::swarm::sync::{ChangeSet, SyncEvent}; @@ -52,6 +52,8 @@ pub(crate) struct AppState { /// 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, + /// `doc`'s epoch label and heads, readable without its lock (`Replica::stamps`). + pub(crate) stamp: watch::Receiver, pub(crate) lifecycle: Arc>, @@ -186,10 +188,11 @@ impl AppState { *self.epoch_tx.borrow() } - /// The local epoch and `Replica::epoch_seq`, read together. - pub(crate) async fn epoch_stamp(&self) -> (Epoch, u32) { - let replica = self.doc.read().await; - (replica.epoch, replica.epoch_seq) + /// The local epoch and `Replica::epoch_seq`, read together, without waiting for the + /// document's lock. + pub(crate) fn epoch_stamp(&self) -> (Epoch, u32) { + let stamp = self.stamp.borrow(); + (stamp.epoch, stamp.epoch_seq) } pub(crate) async fn is_ready(&self) -> bool { -- cgit v1.3.1