#semaphore #thread #lazy-evaluation #rate-limiting #limit #frequency #execution

raliguard

为您的异步代码频率执行实现惰性速率限制信号量的实现

4个版本

0.1.3 2022年5月29日
0.1.2 2022年5月27日
0.1.1 2022年5月19日
0.1.0 2022年5月18日

#779 in 并发

自定义许可

16KB
77

速率限制守卫

惰性速率限制信号量实现(即无排队固定窗口算法)以控制您的异步代码频率执行


文档lib.rs/raliguard

概述

use std::{thread, sync, time};

use raliguard::Semaphore;


// Create a semaphore with restriction `5 tasks per 1 second`
let originl_sem = Semaphore::new(5, time::Duration::from_secs(1));

// Make it sharable between treads (or you can share between tasks)
let shared_sem = sync::Arc::new(
    sync::Mutex::new(originl_sem)
);

// This is a counter that increments when a thread completed
let shared_done_count = sync::Arc::new(sync::Mutex::new(0));

// Spawn 15 threads
for _ in 0..15 {
    let cloned_sem = shared_sem.clone();
    let cloned_done_state = shared_done_count.clone();
    let thread = thread::spawn(move || {
        let mut local_sem = cloned_sem.lock().unwrap();

        // Get required delay
        let calculated_delay = local_sem.calc_delay();
        drop(local_sem);

        // If delay exists, sleep it
        if let Some(delay) = calculated_delay {
            dbg!(&delay);
            thread::sleep(delay);
        }

        // Mark the thread is done
        let mut local_done_count = cloned_done_state.lock().unwrap();
        *local_done_count += 1;

    });
}

// So sleep 1 second (add some millis to let threads complete incrementing)
thread::sleep(time::Duration::from_secs(1) + time::Duration::from_millis(50));
let cloned_done_count = shared_done_count.clone();
let current_done = cloned_done_count.lock().unwrap();

// And then maximum 10 threads should be completed
// after 1 second sleeping
// (the first 5 with no delay and the another 5 after 1 second)
assert_eq!(*current_done, 10);

特性

  • 睡眠计算的延迟可以与任何异步/await运行时后端或线程一起使用
  • 用于保存调用数据的最低内存使用量

无运行时依赖