diff options
| author | tv <tv@krebsco.de> | 2026-11-01 13:19:04 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-01 13:19:04 +0100 |
| commit | 7a5a7408179c5fe9943bd2ce60295e86f1afaa40 (patch) | |
| tree | 166284a6b05f1f3e5d5166c38eda33088ae5461b /src/remake/mod.rs | |
| parent | b4aa16f2a3c3f9dc0d4eb6e7399bd7ffe269d669 (diff) | |
document: reject writes during rejoin
Diffstat (limited to 'src/remake/mod.rs')
| -rw-r--r-- | src/remake/mod.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/remake/mod.rs b/src/remake/mod.rs index e9d3021..04e9d8a 100644 --- a/src/remake/mod.rs +++ b/src/remake/mod.rs @@ -53,7 +53,7 @@ use axum::{ use tokio::sync::broadcast; use crate::document::replica::Epoch; -use crate::document::store::ChangeSet; +use crate::document::store::{ChangeSet, StoreError}; use crate::document::{Document, Transaction}; /// Remakes and their aftermath on this node, in numbers (`/admin/stats`). @@ -184,12 +184,18 @@ pub(crate) trait Host: Clone + Send + Sync + 'static { F: FnOnce(&Document) -> T + Send + 'static, T: Send + 'static; - /// One committed change (rolled back on error), published and replicated. + /// One committed change (rolled back on error), published and replicated. Refused + /// (`StoreError::Rejoining`) while the document isn't writable: from a rejoin's + /// swap until [`Host::accept_writes`]. fn commit_doc<T, E, F>(&self, f: F) -> impl Future<Output = Result<T, E>> + Send where F: FnOnce(&mut Transaction<'_>) -> Result<T, E> + Send + 'static, T: Send + 'static, - E: Send + 'static; + E: From<StoreError> + Send + 'static; + + /// Lets writes in again, after a rejoin swapped in a document that took none + /// ([`Host::switch_epoch`] with `writable` false). + fn accept_writes(&self) -> impl Future<Output = ()> + Send; /// Applies a change downloaded from peers (`fetch_change`), then publishes it like /// a change received by sync. @@ -199,11 +205,13 @@ pub(crate) trait Host: Clone + Send + Sync + 'static { ) -> impl Future<Output = Result<(), String>> + Send; /// Replaces the document and its epoch atomically. Under the write lock, `f` gets - /// the live document and returns the new one. Afterwards the node resets every - /// peer's sync state and publishes the change. Returns the old document. + /// the live document and returns the new one, which takes writes if `writable` + /// (a rejoin's fresh document doesn't). Afterwards the node resets every peer's + /// sync state and publishes the change. Returns the old document. fn switch_epoch<E, F>( &self, epoch: Epoch, + writable: bool, f: F, ) -> impl Future<Output = Result<Document, E>> + Send where |
