#future #semaphore #rate-limiting #concurrency #rust

futures-rate

这个库提供了易于使用的工具,帮助Rust应用程序避免关键资源或代码路径被压垮。

6个版本

0.1.5 2019年12月16日
0.1.4 2019年12月12日

#827 in 异步

MIT 许可证

29KB
550

futures-rate

futures-rate on crates.io futures-rate on docs.rs

这个库是什么

这个库提供了易于使用的工具,帮助Rust应用程序避免关键资源或代码路径被压垮。

根据配置,库将限制并发轮询受保护未来的数量。

如何使用

安装

首先,将依赖项添加到你的Rust项目中

$ cargo install futures-rate

或在你的项目的 Cargo.toml 中,添加以下依赖项

[dependencies]
futures-rate = "^0.1.0"

然后,从项目的根目录在终端中运行 $ cargo install

限制访问速率

  • 在主线程中创建和管理一个 GateKeeper 对象,这将设置对特定资源的访问限制
use futures_rate::GateKeeper;

/// then in main thread
fn main() {
    // ... other code

    // At most 10 futures can pass the gate at any given time  
    let gatekeeper = GateKeeper::new(10);

    // ... more code
}
  • 然后将你的future注册到 GateKeeper,以便受保护的future可以受到保护
use futures_rate::{GateKeeper, Permit};

/// in the business logic which has access to the `gatekeeper` object
async fn work(gatekeeper: &GateKeeper) -> usize {
    // create the IO-heavy future
    let ioFut = async { 
        // do async work here 
    };

    let permit = gatekeeper.register(async {
        // At most 10 IO work can be on-the-fly at any given time
        ioFut.await;        
        
        // the result of all questions is always 42
        42
    });
    
    permit.await
}

原始Future锁

如果设置

示例

一个典型的用例是将一个 GateKeeper 放置在一个客户端套接字池上,这样只有有限数量的future访客被允许轮询资源,从而限制打开的连接数。

use futures::{executor, future};
use futures_rate::{GateKeeper, Permit};
use std::future::Future;
use std::thread;
use std::time::Duration;

fn main() {
    let gatekeeper = GateKeeper::new(1);
    let fut_values = async {
        let fut_1 = build_fut(0, &gatekeeper);
        let fut_2 = build_fut(1, &gatekeeper);
        let fin = future::join(fut_1, fut_2);
        fin.await
    };

    let values = executor::block_on(fut_values);

    println!("Values from fut_1={:?}", values.0);
    println!("Values from fut_2={:?}", values.1);
}

fn build_fut(
    offset: i32,
    gatekeeper: &GateKeeper,
) -> Permit<Vec<i32>, impl Future<Output = Vec<i32>>> {
    gatekeeper.register(async move {
        let mut values = Vec::with_capacity(100);
        (0..100).for_each(|v| {
            thread::sleep(Duration::from_millis(1));
            values.push(2 * v + offset);
        });

        values
    }).unwrap()
}

依赖项

~215KB