Struct leaky_bucket::RateLimiter
source · pub struct RateLimiter { /* private fields */ }
Expand description
A token-bucket rate limiter.
Implementations§
source§impl RateLimiter
impl RateLimiter
sourcepub fn builder() -> Builder
pub fn builder() -> Builder
Construct a new Builder
for a RateLimiter
.
§Examples
use leaky_bucket::RateLimiter;
use tokio::time::Duration;
let limiter = RateLimiter::builder()
.initial(100)
.refill(100)
.max(1000)
.interval(Duration::from_millis(250))
.fair(false)
.build();
sourcepub fn refill(&self) -> usize
pub fn refill(&self) -> usize
Get the refill amount of this rate limiter as set through
Builder::refill
.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.refill(1024)
.build();
assert_eq!(limiter.refill(), 1024);
sourcepub fn interval(&self) -> Duration
pub fn interval(&self) -> Duration
Get the refill interval of this rate limiter as set through
Builder::interval
.
§Examples
use leaky_bucket::RateLimiter;
use tokio::time::Duration;
let limiter = RateLimiter::builder()
.interval(Duration::from_millis(1000))
.build();
assert_eq!(limiter.interval(), Duration::from_millis(1000));
sourcepub fn max(&self) -> usize
pub fn max(&self) -> usize
Get the max value of this rate limiter as set through Builder::max
.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.max(1024)
.build();
assert_eq!(limiter.max(), 1024);
sourcepub fn is_fair(&self) -> bool
pub fn is_fair(&self) -> bool
Test if the current rate limiter is fair as specified through
Builder::fair
.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.fair(true)
.build();
assert_eq!(limiter.is_fair(), true);
sourcepub fn balance(&self) -> usize
pub fn balance(&self) -> usize
Get the current token balance.
This indicates how many tokens can be requested without blocking.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.initial(100)
.build();
assert_eq!(limiter.balance(), 100);
limiter.acquire(10).await;
assert_eq!(limiter.balance(), 90);
sourcepub fn acquire_one(&self) -> Acquire<'_> ⓘ
pub fn acquire_one(&self) -> Acquire<'_> ⓘ
Acquire a single permit.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.initial(10)
.build();
limiter.acquire_one().await;
sourcepub fn acquire(&self, permits: usize) -> Acquire<'_> ⓘ
pub fn acquire(&self, permits: usize) -> Acquire<'_> ⓘ
Acquire the given number of permits, suspending the current task until they are available.
If zero permits are specified, this function never suspends the current task.
§Examples
use leaky_bucket::RateLimiter;
let limiter = RateLimiter::builder()
.initial(10)
.build();
limiter.acquire(10).await;
sourcepub fn try_acquire(&self, permits: usize) -> bool
pub fn try_acquire(&self, permits: usize) -> bool
Try to acquire the given number of permits, returning true
if the
given number of permits were successfully acquired.
If the scheduler is fair, and there are pending tasks waiting to acquire
tokens this method will return false
.
If zero permits are specified, this method returns true
.
§Examples
use leaky_bucket::RateLimiter;
use tokio::time;
let limiter = RateLimiter::builder().refill(1).initial(1).build();
assert!(limiter.try_acquire(1));
assert!(!limiter.try_acquire(1));
assert!(limiter.try_acquire(0));
time::sleep(limiter.interval() * 2).await;
assert!(limiter.try_acquire(1));
assert!(limiter.try_acquire(1));
assert!(!limiter.try_acquire(1));
sourcepub fn acquire_owned(self: Arc<Self>, permits: usize) -> AcquireOwned ⓘ
pub fn acquire_owned(self: Arc<Self>, permits: usize) -> AcquireOwned ⓘ
Acquire a permit using an owned future.
If zero permits are specified, this function never suspends the current task.
This required the RateLimiter
to be wrapped inside of an
std::sync::Arc
but will in contrast permit the acquire operation to
be owned by another struct making it more suitable for embedding.
§Examples
use leaky_bucket::RateLimiter;
use std::sync::Arc;
let limiter = Arc::new(RateLimiter::builder().initial(10).build());
limiter.acquire_owned(10).await;
Example when embedded into another future. This wouldn’t be possible
with RateLimiter::acquire
since it would otherwise hold a reference
to the corresponding RateLimiter
instance.
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use leaky_bucket::{AcquireOwned, RateLimiter};
use pin_project::pin_project;
#[pin_project]
struct MyFuture {
limiter: Arc<RateLimiter>,
#[pin]
acquire: Option<AcquireOwned>,
}
impl Future for MyFuture {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
loop {
if let Some(acquire) = this.acquire.as_mut().as_pin_mut() {
futures::ready!(acquire.poll(cx));
return Poll::Ready(());
}
this.acquire.set(Some(this.limiter.clone().acquire_owned(100)));
}
}
}
let limiter = Arc::new(RateLimiter::builder().initial(100).build());
let future = MyFuture { limiter, acquire: None };
future.await;