Struct leaky_bucket::RateLimiter

source ·
pub struct RateLimiter { /* private fields */ }
Expand description

A token-bucket rate limiter.

Implementations§

source§

impl RateLimiter

source

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();
source

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);
source

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));
source

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);
source

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);
source

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);
source

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;
source

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;
source

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));
source

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;

Trait Implementations§

source§

impl Debug for RateLimiter

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Send for RateLimiter

source§

impl Sync for RateLimiter

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.