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 | 59833811cce25f03efbdc889f806ad75804942ab (patch) | |
| tree | 5a36fcbf81333fac9374b01ecacca04ef8590179 /src/document | |
| parent | 5decfdba9e8985b72301acb288e26a6d1de50d58 (diff) | |
document: reject writes during rejoin
Diffstat (limited to 'src/document')
| -rw-r--r-- | src/document/replica.rs | 7 | ||||
| -rw-r--r-- | src/document/store.rs | 4 |
2 files changed, 11 insertions, 0 deletions
diff --git a/src/document/replica.rs b/src/document/replica.rs index 27c81ad..61f2b3b 100644 --- a/src/document/replica.rs +++ b/src/document/replica.rs @@ -113,6 +113,12 @@ pub(crate) struct Replica { /// run: messages carry it, so a late one can't flip a peer's view of our epoch back. pub(crate) epoch_seq: u32, pub(crate) doc: Document, + /// Whether writes go in (`AppState::mutate_doc`). False while a rejoin syncs a fresh + /// document: a write would land in a document the epoch's snapshot hasn't reached + /// yet, or be thrown away with it if the rejoin is abandoned. Cleared and set again + /// in the same lock as the swap (`Host::switch_epoch`), so no write checked + /// before a swap lands after it. + pub(crate) writable: bool, heads: Vec<ChangeHash>, stamp: watch::Sender<Stamp>, } @@ -138,6 +144,7 @@ impl Replica { epoch, epoch_seq: 0, doc, + writable: true, heads: Vec::new(), stamp, }; diff --git a/src/document/store.rs b/src/document/store.rs index 0a3c8ad..45d46cd 100644 --- a/src/document/store.rs +++ b/src/document/store.rs @@ -94,6 +94,10 @@ pub(crate) enum StoreError { /// An index past a list's end (`length` items). #[error("index {index} is past the list's end ({length} items)")] PastTheEnd { index: usize, length: usize }, + /// The node is rejoining a newer epoch: no writes until it is done + /// (`Replica::writable`). + #[error("the node is rejoining a newer epoch; writes are refused until it is done")] + Rejoining, #[error(transparent)] Doc(#[from] automerge::AutomergeError), #[error(transparent)] |
