Expand description
Stale-term fencing for a returning ex-primary (issue #835, PRD #819, ADR 0030).
After a failover the cluster serves a new term. A former primary that rejoins on its old, stale term must not be able to corrupt the new timeline — its term-stamped writes and its stream handshakes have to be refused until it re-syncs and adopts the new term. This module is the reusable term-comparison primitive both fencing boundaries share:
- Apply boundary — a replica rejects a WAL/logical record whose term
is behind its current term. The live replica apply path enforces this
directly in
super::logical::LogicalChangeApplier::apply(it already tracks the last-applied term);TermFence::admit_recordis the same rule expressed over a durable term so it survives a restart. - Handshake boundary — when a node opens a replication stream it
declares the term it is streaming under.
TermFence::admit_handshakerefuses a handshake whose declared term is behind the current term, so a stale ex-primary cannot even establish the stream. - Lease boundary — a serverless writer lease is stamped with the term it was taken under; a holder whose term is behind the current term fails closed before mutating remote artifacts.
The decision is deliberately the data-path twin of the election-side
super::RefusalReason::StaleTerm:
incoming == current→ admit at the live term;incoming > current→ a newer timeline supersedes ours, so adopt the new term (persisted durably) and then admit. This is how a replica moves forward when the legitimate new primary streams to it;incoming < current→ fenced: a superseded primary, refused.
The current term is held behind a TermStore so adoption is durable —
a replica that crashes after adopting term N comes back fencing stale
term N-1 records rather than briefly accepting them. Production wires the
file-backed store alongside the node’s other durable replication state;
tests use the in-memory store.
Structs§
- File
Term Store - Memory
Term Store - In-memory term store for tests and ephemeral nodes.
- Stale
Term Fenced - Why the term fence refused a message: the incoming term is behind the current term, so the sender is a deposed primary on a superseded timeline.
- Stream
Handshake - A replication-stream handshake as seen by the admitting replica.
- Term
Fence - The stale-term fence. Wraps a durable
TermStoreand applies the term rule at the apply and handshake boundaries.
Enums§
- Fence
Boundary - The boundary at which a term-stamped message is being admitted. Only affects diagnostics — the term rule is identical at both.
- Fence
Verdict - The verdict of the term fence for one incoming term-stamped message.
- Term
Store Error - Error reading or persisting the durable current term.
Traits§
- Term
Store - Durable store for a node’s current replication term. The default (when
nothing was ever written) is
DEFAULT_REPLICATION_TERM, matching the term records carry before any failover.
Functions§
- term_
is_ stale - The one shared stale-term predicate: only a strictly older incoming term is stale. Equal terms are retries; newer terms are adoption candidates.