Skip to main content

IdempotencyStore

Struct IdempotencyStore 

Source
pub struct IdempotencyStore { /* private fields */ }
Expand description

Store for tracking idempotent request deduplication.

The remote node uses this to prevent duplicate execution while an operation is in flight and during the configured post-terminal retention window. The guarantee does not survive store reset or terminal-record eviction. When a SpawnRequest arrives:

  1. Atomically check and record the idempotency key
  2. If new: execute the already-recorded operation
  3. If duplicate: attach to the canonical task or return its cached outcome
  4. If conflict (same key, different params): reject

In-flight entries are retained for the operation lifetime. Once an entry is completed, it is retained for the configured TTL so retries can observe the canonical outcome. Callers must complete every admitted entry when the operation reaches a terminal state.

§Thread Safety

The store is designed for single-threaded use within the deterministic lab runtime. For production multi-threaded use, wrap in a lock.

Implementations§

Source§

impl IdempotencyStore

Source

pub fn new(default_ttl: Duration) -> Self

Creates a new idempotency store with the given default TTL.

Source

pub fn check_and_record( &mut self, key: IdempotencyKey, remote_task_id: RemoteTaskId, request: IdempotencyRequestFingerprint, now: Time, ) -> DedupDecision

Atomically checks a request and records it when it is new.

A DedupDecision::New result guarantees that the supplied key and canonical task ID were inserted before this method returned. Holding the store’s exclusive borrow across both steps prevents a caller-visible check/record gap.

Source

pub fn complete( &mut self, key: &IdempotencyKey, remote_task_id: RemoteTaskId, outcome: RemoteOutcome, now: Time, ) -> bool

Updates the outcome of the canonical task and starts its terminal-result retention window at now.

The task ID fences record generations after an expired key is admitted again. A delayed completion from the previous generation is rejected.

Returns true if the matching canonical record was found and updated.

Source

pub fn evict_expired(&mut self, now: Time) -> usize

Evicts terminal entries whose retention deadline has elapsed.

In-flight entries are never evicted by this method.

Returns the number of entries evicted.

Source

pub fn len(&self) -> usize

Returns the number of entries in the store.

Source

pub fn is_empty(&self) -> bool

Returns true if the store is empty.

Trait Implementations§

Source§

impl Debug for IdempotencyStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V