#[cfg(test)]
mod tests {
use anyhow::Result;
use async_throttle::RateLimiter;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::Mutex;
#[tokio::test]
async fn test_throttle_empty() -> Result<()> {
let rate_limiter = RateLimiter::new(Duration::from_millis(10));
let start = Instant::now();
for _ in 0..10 {
rate_limiter.throttle(|| async {}).await;
}
let end = start.elapsed().as_millis();
assert!(end >= 89);
Ok(())
}
#[tokio::test]
async fn test_throttle_fn() -> Result<()> {
let rate_limiter = RateLimiter::new(Duration::from_millis(10));
async fn hello() {
println!("Hello, world!")
}
let start = Instant::now();
for _ in 0..10 {
rate_limiter.throttle(hello).await;
}
let end = start.elapsed().as_millis();
assert!(end >= 89);
Ok(())
}
#[tokio::test]
async fn test_throttle_with_mutable_data() -> Result<()> {
let rate_limiter = Arc::new(RateLimiter::new(Duration::from_millis(10)));
let data = Arc::new(Mutex::new(0));
async fn hello(data: Arc<Mutex<i32>>) {
let mut data = data.lock().await;
*data += 1;
}
let start = Instant::now();
let futs = (0..10).map(|_| {
let data = data.clone();
let rate_limiter = rate_limiter.clone();
tokio::spawn(async move {
rate_limiter.throttle(|| hello(data.clone())).await;
Ok::<(), anyhow::Error>(())
})
});
for fut in futs {
fut.await??;
}
let end = start.elapsed().as_millis();
let data = data.lock().await;
assert!(end >= 89);
assert_eq!(*data, 10);
Ok(())
}
#[tokio::test]
async fn test_throttle_fn_mut_with_mutable_data_2() -> Result<()> {
let data = Arc::new(Mutex::new(Data { data: 0 }));
let rate_limiter = Arc::new(RateLimiter::new(Duration::from_millis(10)));
struct Data {
data: i32,
}
impl Data {
async fn increment(&mut self) {
self.data += 1;
}
}
async fn hello(data: Arc<Mutex<Data>>) {
let mut data = data.lock().await;
data.increment().await;
}
let start = Instant::now();
let futs = (0..10).map(|_| {
let data = data.clone();
let rate_limiter = rate_limiter.clone();
tokio::spawn(async move {
rate_limiter.throttle(|| hello(data.clone())).await;
Ok::<(), anyhow::Error>(())
})
});
for fut in futs {
fut.await??;
}
let end = start.elapsed().as_millis();
let data = data.lock().await;
assert!(end >= 89);
assert_eq!(data.data, 10);
Ok(())
}
}