pub struct RateLimit { /* private fields */ }Expand description
A rate limiter, usable as a plugin or as scoped middleware.
Construct with per_second,
per_minute, per_hour or
per, then refine with burst and
by.
Cloning shares the underlying table, so the same limiter can be installed in several places and still count one budget.
Implementations§
Source§impl RateLimit
impl RateLimit
Sourcepub fn per(limit: u32, period: Duration) -> Self
pub fn per(limit: u32, period: Duration) -> Self
Allow limit requests per period, per key.
The initial burst equals limit: a key that has been quiet may spend
its whole allowance at once and then refills at limit / period. Narrow
that with burst.
§Panics
If limit is zero, or period is zero. Both describe a limiter that
can never admit anything, which is a configuration mistake rather than a
policy, and failing at startup is the repo’s rule for those.
Sourcepub fn per_second(limit: u32) -> Self
pub fn per_second(limit: u32) -> Self
Allow limit requests per second, per key.
Sourcepub fn per_minute(limit: u32) -> Self
pub fn per_minute(limit: u32) -> Self
Allow limit requests per minute, per key.
Sourcepub fn burst(self, burst: u32) -> Self
pub fn burst(self, burst: u32) -> Self
Cap the instantaneous burst at burst requests.
The sustained rate is unchanged. burst(1) admits no burst at all:
requests must be spaced by a full emission interval.
§Panics
If burst is zero.
Sourcepub fn by<F>(self, f: F) -> Self
pub fn by<F>(self, f: F) -> Self
Derive the bucket key from the call instead of using the peer IP.
Returning None exempts the request from limiting entirely, which is
how you let health checks or an authenticated internal caller through.
The key is hashed and dropped rather than kept, so its length costs nothing beyond the one call and a caller-supplied value needs no length check of its own before it is handed over.
use churust_ratelimit::RateLimit;
// Per API key, falling back to no limit for unauthenticated callers.
let limiter = RateLimit::per_minute(60)
.by(|call| call.header("x-api-key").map(str::to_owned));Sourcepub fn max_keys(self, n: usize) -> Self
pub fn max_keys(self, n: usize) -> Self
Set how many keys are tracked before the table is pruned.
The table holds a 64-bit digest of the key and one timestamp per active
client, so an entry costs the same whatever the key is and the default of
100,000 is a few megabytes for any by function. Raise
it for a large fleet, lower it for a memory-constrained deployment.
§Panics
If n is zero.
Trait Implementations§
Source§impl Middleware for RateLimit
impl Middleware for RateLimit
Source§fn handle<'life0, 'async_trait>(
&'life0 self,
call: Call,
next: Next,
) -> Pin<Box<dyn Future<Output = Response> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn handle<'life0, 'async_trait>(
&'life0 self,
call: Call,
next: Next,
) -> Pin<Box<dyn Future<Output = Response> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
next.run(call) to
proceed, and return the (possibly post-processed) response.Source§impl Plugin for RateLimit
impl Plugin for RateLimit
Source§fn install(self: Box<Self>, app: &mut AppBuilder)
fn install(self: Box<Self>, app: &mut AppBuilder)
Installed in Phase::Plugins, so a rejected request is still logged by
a CallLogging plugin sitting in Phase::Monitoring outside it.