Skip to main content

RateLimitCounter

Trait RateLimitCounter 

Source
pub trait RateLimitCounter:
    Send
    + Sync
    + 'static {
    // Required method
    fn count<'a>(
        &'a self,
        key: &'a str,
        window: u64,
        window_secs: u64,
    ) -> Pin<Box<dyn Future<Output = A2aResult<u64>> + Send + 'a>>;
}
Expand description

A request counter every replica shares.

One method, because one is all a fixed-window limiter needs: the count for a (caller, window) pair after this request is included. The interceptor owns the policy — what the window is, what the limit is, what to do when the count exceeds it — so an implementation only has to count.

§Contract

count must be atomic: two replicas incrementing the same (key, window) concurrently must see two different totals, and no request may go uncounted. A read-then-write implementation loses increments under exactly the concurrency this exists to handle, which is the one bug that would make a shared counter worse than no shared counter — it would look like it was working.

Keys are caller identities and are attacker-influenced (an authenticated subject, or a client address). Treat them as untrusted input: PostgresRateLimitCounter (the postgres feature) binds them as parameters rather than interpolating them.

§Errors

Return Err when the count could not be established. The interceptor treats that as “the shared counter is unavailable” and falls back to counting locally, so an implementation should not swallow failures and return a fabricated count — a made-up number admits or rejects traffic on no evidence, where an error degrades to the per-process behaviour that was the status quo.

Required Methods§

Source

fn count<'a>( &'a self, key: &'a str, window: u64, window_secs: u64, ) -> Pin<Box<dyn Future<Output = A2aResult<u64>> + Send + 'a>>

Counts one request against key in window, returning the new total.

window is the fixed-window number the interceptor computed (unix_seconds / window_secs), passed in rather than derived so every replica agrees on the boundary without needing synchronised clocks beyond what they already have.

window_secs is the window’s width, for implementations that expire their own rows or set a TTL.

§Errors

A2aError when the backing store cannot be reached or the count cannot be established.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§