Skip to main content

RateLimitStore

Trait RateLimitStore 

pub trait RateLimitStore:
    Send
    + Sync
    + 'static {
    // Required method
    fn consume<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 str,
        config: RateLimitConfig,
    ) -> Pin<Box<dyn Future<Output = Result<RateLimitDecision, CratestackError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;

    // Provided method
    fn consume_bounded<'life0, 'life1, 'async_trait>(
        &'life0 self,
        request: ConsumeRequest<'life1>,
    ) -> Pin<Box<dyn Future<Output = Result<BoundedOutcome, CratestackError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait { ... }
}
Expand description

Pluggable storage for token-bucket state. Implementations must be safe to share across tasks (use a Mutex internally, or rely on the backing store’s atomicity).

Required Methods§

fn consume<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, config: RateLimitConfig, ) -> Pin<Box<dyn Future<Output = Result<RateLimitDecision, CratestackError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Atomically consume one token for key. Returns the decision based on the bucket state after the consumption attempt.

Provided Methods§

fn consume_bounded<'life0, 'life1, 'async_trait>( &'life0 self, request: ConsumeRequest<'life1>, ) -> Pin<Box<dyn Future<Output = Result<BoundedOutcome, CratestackError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Consume one token, honouring a BucketBudget on how many distinct buckets the request’s scope may create (cratestack#871).

The default implementation ignores the budget and reports Charged::Unbounded, so a third-party store written against the pre-#871 trait keeps compiling and behaving exactly as before — at the cost of leaving the keyspace unbounded for its deployment. The middleware logs that (throttled) rather than failing, because the alternative is breaking every out-of-tree store on upgrade.

Implementations MUST keep the “does this scope already know this bucket / may it learn a new one / charge the fallback” decision atomic with the token consumption. Doing it as two round-trips re-opens the race the budget exists to close: N concurrent requests each observing SCARD < max all create a bucket.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§