RateLimiter

Struct RateLimiter 

Source
pub struct RateLimiter { /* private fields */ }
Expand description

A rate limiter, or time barrier to prevent continuing execution before given time passes. Used mainly for things like dealing with remote API DOS protection.

Implementations§

Source§

impl RateLimiter

Source

pub fn new(count: usize, duration: Duration) -> Self

Creates a new RateLimiter that prevents an async task from continuing too quickly.

§Example:
use std::time::Duration;
use arl::RateLimiter;
let limiter = RateLimiter::new(75, Duration::from_secs(60));
async {
loop {
        limiter.wait().await;
        // Call a remote api here.
        // This will ensure that the remote api will not be hit more than 75 times in 60 seconds block.
     }
};

RateLimiter can be cloned and send to other threads: it will use the same counter and limits for all the threads.

Examples found in repository?
examples/simple.rs (line 9)
7async fn main() {
8    // Limit rate to 10 times in 2 seconds.
9    let limiter = RateLimiter::new(10, Duration::from_secs(2));
10    let counter = Arc::new(Mutex::new(0));
11    // Spawn 4 threads.
12    for i in 0..4 {
13        // RateLimiter can be cloned - all threads will use the same timer/stats underneath.
14        let limiter = limiter.clone();
15        let counter = counter.clone();
16        tokio::spawn(async move {
17            // Do things in a loop. Notice there is no `sleep` in here.
18            loop {
19                // Wait if needed. First 10 will be executed immediately.
20                limiter.wait().await;
21                // Increment and show counter just for fun.
22                let mut c = counter.lock().unwrap();
23                *c += 1;
24                println!("Counter: {} by thread #{}", c, i);
25            }
26        });
27    }
28    // Let other threads do some work.
29    sleep(Duration::from_secs(21));
30}
Source

pub async fn wait(&self)

Make the current task wait until given limits have passed. Uses tokio::time::sleep() internally, so it allows other tasks to continue in the meantime.

§Example:
use std::time::Duration;
use arl::RateLimiter;
let limiter = RateLimiter::new(2, Duration::from_secs(1));
async {
    loop {
        limiter.wait().await;
        // continue here knowing that it won't be executed more than twice in a second
    }   
};
Examples found in repository?
examples/simple.rs (line 20)
7async fn main() {
8    // Limit rate to 10 times in 2 seconds.
9    let limiter = RateLimiter::new(10, Duration::from_secs(2));
10    let counter = Arc::new(Mutex::new(0));
11    // Spawn 4 threads.
12    for i in 0..4 {
13        // RateLimiter can be cloned - all threads will use the same timer/stats underneath.
14        let limiter = limiter.clone();
15        let counter = counter.clone();
16        tokio::spawn(async move {
17            // Do things in a loop. Notice there is no `sleep` in here.
18            loop {
19                // Wait if needed. First 10 will be executed immediately.
20                limiter.wait().await;
21                // Increment and show counter just for fun.
22                let mut c = counter.lock().unwrap();
23                *c += 1;
24                println!("Counter: {} by thread #{}", c, i);
25            }
26        });
27    }
28    // Let other threads do some work.
29    sleep(Duration::from_secs(21));
30}

Trait Implementations§

Source§

impl Clone for RateLimiter

Source§

fn clone(&self) -> RateLimiter

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RateLimiter

Source§

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

Formats the value using the given formatter. Read more

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

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>,

Source§

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.