From 59833811cce25f03efbdc889f806ad75804942ab Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 1 Nov 2026 13:19:04 +0100 Subject: document: reject writes during rejoin --- src/state/host.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/state/host.rs') diff --git a/src/state/host.rs b/src/state/host.rs index 24a989e..6bb9d3b 100644 --- a/src/state/host.rs +++ b/src/state/host.rs @@ -12,7 +12,7 @@ use tracing::debug; use super::{AppState, HelloState, NodeLifecycle, StaleView, Standing}; use crate::document::replica::Epoch; -use crate::document::store::ChangeSet; +use crate::document::store::{ChangeSet, StoreError}; use crate::document::{ChangeHash, Document, ReadDoc, Transaction}; use crate::remake::{Host, PeerSummary, RemakeState}; @@ -220,12 +220,22 @@ impl Host for AppState { where F: FnOnce(&mut Transaction<'_>) -> Result + Send + 'static, T: Send + 'static, - E: Send + 'static, + E: From + Send + 'static, { let state = self.clone(); async move { state.mutate_doc(f).await } } + fn accept_writes(&self) -> impl Future + Send { + let state = self.clone(); + async move { + // On the blocking pool, as every write lock is taken. + tokio::task::spawn_blocking(move || state.doc.blocking_write().writable = true) + .await + .expect("document write task panicked"); + } + } + fn apply_change( &self, change: crate::document::Change, @@ -255,6 +265,7 @@ impl Host for AppState { fn switch_epoch( &self, epoch: Epoch, + writable: bool, f: F, ) -> impl Future> + Send where @@ -271,6 +282,7 @@ impl Host for AppState { let old_doc = std::mem::replace(&mut replica.doc, new_doc); replica.epoch = epoch; replica.epoch_seq += 1; + replica.writable = writable; replica.refresh_heads(); // Updated under the same lock, so the cached epoch never disagrees // with the document for anyone holding the lock. -- cgit v1.3.1