Ritlers
A task-length aware rate limiter for Rust, useful for calling APIs that apply strict rate limiting.
Why ritlers?
Most rate limiters count when a task starts. Because network requests have variable latency, and due to the possibility of caching in underlying libraries, this can still cause too large bursts to arrive at a downstream server simultaneously. Ritlers instead waits for each task to finish before its slot becomes available again, so the rate limit is respected regardless of how long individual requests take.
When tasks complete instantly the behaviour is identical to a standard token-bucket limiter.
Features
- Blocking (
blocking— default): parks the calling thread until a slot is free - Async (
async): non-blocking, backed by Tokio - Retry support: return
TaskResult::TryAgainfrom a scheduled task to re-queue it ahead of newly scheduled tasks, orTaskResult::Doneto stop
Usage
Blocking
schedule_task blocks the calling thread until a slot is free and returns the Instant the task finished.
// 2 requests per second
let mut limiter = new.unwrap;
let finished_at = limiter.schedule_task;
// Retry on rate-limit errors; stop otherwise
limiter.schedule_task_with_retry;
Async
schedule_task and schedule_task_with_retry both return a Duration estimating how long until the task starts, based on the current queue depth. This can be shown to users or used for logging.
// 2 requests per second
let limiter = new.unwrap;
let eta = limiter.schedule_task.await;
println!;
// Retry on rate-limit errors; stop otherwise
limiter.schedule_task_with_retry.await;
TaskResult
| Variant | Meaning |
|---|---|
Done |
Task is finished (any outcome); release the slot |
TryAgain |
Re-queue ahead of newly scheduled tasks and retry |