Skip to main content

IdempotencyStore

Trait IdempotencyStore 

Source
pub trait IdempotencyStore:
    Send
    + Sync
    + 'static {
    // Required methods
    fn reserve_or_fetch<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        principal: &'life1 str,
        key: &'life2 str,
        request_hash: [u8; 32],
        expires_at: SystemTime,
    ) -> Pin<Box<dyn Future<Output = Result<ReservationOutcome, CoolError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;
    fn complete<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
        &'life0 self,
        principal: &'life1 str,
        key: &'life2 str,
        token: Uuid,
        status: u16,
        headers: &'life3 [u8],
        body: &'life4 [u8],
    ) -> Pin<Box<dyn Future<Output = Result<(), CoolError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait,
             Self: 'async_trait;
    fn release<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        principal: &'life1 str,
        key: &'life2 str,
        token: Uuid,
    ) -> Pin<Box<dyn Future<Output = Result<(), CoolError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;
}

Required Methods§

Source

fn reserve_or_fetch<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, principal: &'life1 str, key: &'life2 str, request_hash: [u8; 32], expires_at: SystemTime, ) -> Pin<Box<dyn Future<Output = Result<ReservationOutcome, CoolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Atomically reserve (principal, key) for the caller, or report the outcome of an existing reservation. Implementations MUST be concurrent-safe: two simultaneous callers seeing the same key and hash must observe exactly one Reserved and one InFlight, never two Reserved. The expires_at argument bounds the reservation’s lifetime so a forgotten release doesn’t pin the key forever; when a retry reclaims an expired row the store MUST rotate the reservation token so complete/release from the original handler can no longer touch the newer slot.

Source

fn complete<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, principal: &'life1 str, key: &'life2 str, token: Uuid, status: u16, headers: &'life3 [u8], body: &'life4 [u8], ) -> Pin<Box<dyn Future<Output = Result<(), CoolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, Self: 'async_trait,

Persist the captured response for a previously-reserved key so subsequent attempts replay it. Banks treat the IETF idempotency contract as “freeze the outcome”: if the handler returned 5xx, retries see the same 5xx unless they use a fresh key. The token must match the value returned by reserve_or_fetch when this caller claimed the key; mismatched tokens are silently no-ops so a stale handler whose reservation has been reclaimed cannot overwrite a newer execution’s response.

headers is the encoded blob from super::encode_headers — replays rebuild the response with the same Location, ETag, Cache-Control, Content-Type, etc. that the original handler set.

Source

fn release<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, principal: &'life1 str, key: &'life2 str, token: Uuid, ) -> Pin<Box<dyn Future<Output = Result<(), CoolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Release a reservation without recording a completion (e.g. the inner service panicked or the middleware itself errored before the response was ready). Subsequent attempts with the same key can re-reserve. As with complete, the token must match the active reservation.

Implementors§