Expand description
A lock-free token bucket ratelimiter that can be shared between threads.
The ratelimiter uses scaled tokens internally for sub-token precision, allowing accurate rate limiting at any rate without requiring callers to tune refill intervals.
The std feature is enabled by default and provides StdClock,
Ratelimiter::new, and Ratelimiter::builder. Disable default
features to use the crate in no_std environments and supply your own
Clock.
use ratelimit::Ratelimiter;
// 1000 requests/s, no initial tokens, burst limited to 1 second
let ratelimiter = Ratelimiter::new(1000);
// Custom burst capacity and initial tokens
let ratelimiter = Ratelimiter::builder(1000)
.max_tokens(5000)
.initial_available(100)
.build()
.unwrap();
// Sub-Hz rates: 1 token per minute
let ratelimiter = Ratelimiter::builder(1)
.period(std::time::Duration::from_secs(60))
.build()
.unwrap();
// Rate of 0 means unlimited — try_wait() always succeeds
let ratelimiter = Ratelimiter::new(0);
assert!(ratelimiter.try_wait().is_ok());
// Sleep-wait loop
use ratelimit::TryWaitError;
let ratelimiter = Ratelimiter::new(100);
for _ in 0..10 {
loop {
match ratelimiter.try_wait() {
Ok(()) => break,
Err(TryWaitError::Insufficient(wait)) => std::thread::sleep(wait),
Err(TryWaitError::ExceedsCapacity) => unreachable!("max_tokens > 0"),
Err(_) => unreachable!(),
}
}
// do some ratelimited action here
}use core::time::Duration;
use ratelimit::{Clock, Ratelimiter};
struct FixedClock;
impl Clock for FixedClock {
fn elapsed(&self) -> Duration {
Duration::from_millis(10)
}
}
let ratelimiter = Ratelimiter::with_clock(1000, FixedClock);
assert!(ratelimiter.try_wait().is_ok());Structs§
- Builder
- Builder for constructing a
Ratelimiterwith custom settings. - Ratelimiter
- A lock-free token bucket ratelimiter.
- StdClock
- Standard library clock implementation.
Enums§
- Error
- TryWait
Error - Failure modes for
Ratelimiter::try_waitandRatelimiter::try_wait_n.
Traits§
- Clock
- Abstraction over a monotonic clock.