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§
Sourcefn count<'a>(
&'a self,
key: &'a str,
window: u64,
window_secs: u64,
) -> Pin<Box<dyn Future<Output = A2aResult<u64>> + Send + 'a>>
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".