#future #bounded #rate #rate-limiting #async

futures-ratelimit

未来(FuturesUnordered)和有序未来(FuturesOrdered)的限界版本

2 个稳定版本

1.0.1 2024 年 1 月 16 日
0.1.0 2024 年 1 月 15 日

#416异步

每月下载量:24

MIT 许可证

38KB
638 代码行

Futures-Ratelimit

FuturesUnorderedFuturesOrdered 的限界版本

此 crate 提供了 FuturesUnorderedFuturesOrdered 的限界版本。

通常的 futures 的 FuturesUnorderedFuturesOrdered 结构体不提供任何限制在任何给定时间可以轮询多少个 futures 的手段。虽然你可以使用信号量或其他形式的资源锁定,但这不会阻止异步运行时一次性轮询过多的 futures(从而浪费 CPU)。你也可以使用通道,但这感觉比较麻烦,需要额外的代码和开销。

此 crate 提供了与通常的 futures-(un)ordered 类型行为相同的类型,但你可以在任何给定时间指定可以轮询的最大 futures 数量。这允许你创建和 提交 大量的 futures,而不会使异步运行时过载。还提供了 FuturesOrderedFuturesUnordered100% 互换替代品

此 crate 的逻辑相当简单:我们 覆盖 了底层的 poll_next(),并在需要时,从一个迭代器或队列(由你选择)中弹出新的 future。这意味着我们始终运行 正好 N 个 futures(如果 futures 源已耗尽,则可能更少)。

这些包装类型被设计成仅在需要时执行检查(弹出更多的 futures),从而使一切尽可能高效。

基本示例

use futures_ratelimit::ordered::FuturesOrderedBounded;
use futures_ratelimit::common::Passthrough;
use futures::StreamExt;

async fn dummy() -> u64{
    42
}

let mut fut_unordered = FuturesOrderedBounded::new(5);
for _ in 0..10 {
    fut_unordered.push_back(dummy());
}

// The internal FuturesOrderedBounded will have 5 futures at most.
tokio_test::block_on(async move{
    assert_eq!(fut_unordered.borrow_inner().len(), 5);
    while let Some(value) = fut_unordered.next().await {
        println!("{}", value);
        assert!(fut_unordered.borrow_inner().len() <= 5);
    }
    assert_eq!(fut_unordered.borrow_inner().len(), 0);
    assert!(fut_unordered.borrow_inner().is_empty());
});

请确保查看文档中的示例!

许可证

MIT

备注

这个库的名字故意具有误导性。它原本应该是 futures-bounded,但这个名字已经被 crates.io 上的其他人使用,而 rate-limit 似乎也有类似的意思。

依赖项

~1–1.6MB
~33K SLoC