pub struct LeaseStore { /* private fields */ }Expand description
Wraps an AtomicRemoteBackend with lease primitives. The lease
object is stored under a deterministic key derived from
database_key; the store reads/writes that one key.
The trait bound AtomicRemoteBackend is the type-system version
of “this backend can enforce CAS” — backends that cannot
(Turso, D1, plain HTTP without ETag) deliberately do not
implement the trait, so wiring them into a LeaseStore becomes
a compile error rather than a runtime fail-closed.
Implementations§
Source§impl LeaseStore
impl LeaseStore
pub fn new(backend: Arc<dyn AtomicRemoteBackend>) -> LeaseStore
pub fn with_prefix(self, prefix: impl Into<String>) -> LeaseStore
Sourcepub fn current(
&self,
database_key: &str,
) -> Result<Option<WriterLease>, LeaseError>
pub fn current( &self, database_key: &str, ) -> Result<Option<WriterLease>, LeaseError>
Read whatever lease object is currently published. None means
no lease has ever been written for this key.
Sourcepub fn try_acquire(
&self,
database_key: &str,
holder_id: &str,
ttl_ms: u64,
) -> Result<WriterLease, LeaseError>
pub fn try_acquire( &self, database_key: &str, holder_id: &str, ttl_ms: u64, ) -> Result<WriterLease, LeaseError>
Try to acquire the lease for database_key on behalf of
holder_id, valid for ttl_ms. Returns the WriterLease we
own on success. Errors:
LeaseError::Heldif a different holder owns a non-expired lease.LeaseError::LostRaceif a concurrent contender beat us.
Acquires under the base replication term; use
LeaseStore::try_acquire_for_term to stamp a specific term and
fence stale-term contenders (issue #835).
Sourcepub fn try_acquire_for_term(
&self,
database_key: &str,
holder_id: &str,
ttl_ms: u64,
term: u64,
) -> Result<WriterLease, LeaseError>
pub fn try_acquire_for_term( &self, database_key: &str, holder_id: &str, ttl_ms: u64, term: u64, ) -> Result<WriterLease, LeaseError>
Like LeaseStore::try_acquire but stamps term onto the lease
and fences any contender whose term is behind the published
lease’s term (issue #835, ADR 0030).
The term tie is what makes a deposed primary fail closed: a new
primary that won a higher term takes the lease under that term, so
a returning ex-primary on the old term sees a published lease whose
term is ahead of its own and is refused with LeaseError::Fenced
— even when the lease has since expired and would otherwise be
poachable. A stale holder can never re-take the writer slot until
it adopts the new term.
Sourcepub fn refresh(
&self,
lease: &WriterLease,
ttl_ms: u64,
) -> Result<WriterLease, LeaseError>
pub fn refresh( &self, lease: &WriterLease, ttl_ms: u64, ) -> Result<WriterLease, LeaseError>
Refresh lease.expires_at_ms to now + ttl_ms. Fails with
Stale if the holder/generation no longer matches what’s
currently published. The returned lease is the new
in-effect record.
Sourcepub fn refresh_for_term(
&self,
lease: &WriterLease,
ttl_ms: u64,
current_term: u64,
) -> Result<WriterLease, LeaseError>
pub fn refresh_for_term( &self, lease: &WriterLease, ttl_ms: u64, current_term: u64, ) -> Result<WriterLease, LeaseError>
Refresh the lease, but fail closed if the holder’s term has
fallen behind current_term (issue #835). This is the keep-alive
counterpart to the acquire fence: a primary that was deposed while
holding a live lease cannot keep extending it once the cluster has
moved to a newer term — its next refresh is fenced before it ever
touches the backend, so it stops mutating and drains.
When the holder’s own term still matches or leads current_term,
this is exactly LeaseStore::refresh.
Sourcepub fn release(&self, lease: &WriterLease) -> Result<(), LeaseError>
pub fn release(&self, lease: &WriterLease) -> Result<(), LeaseError>
Release the lease. Only succeeds when the published lease
matches lease.holder_id + lease.generation. A stolen or
already-replaced lease returns Stale.
Auto Trait Implementations§
impl !RefUnwindSafe for LeaseStore
impl !UnwindSafe for LeaseStore
impl Freeze for LeaseStore
impl Send for LeaseStore
impl Sync for LeaseStore
impl Unpin for LeaseStore
impl UnsafeUnpin for LeaseStore
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request