6 个版本

0.1.5 2023 年 9 月 14 日
0.1.4 2023 年 9 月 14 日

#3 in #task-pool

Download history 82/week @ 2024-03-16 83/week @ 2024-03-23 162/week @ 2024-03-30 78/week @ 2024-04-06 242/week @ 2024-04-13 113/week @ 2024-04-20 70/week @ 2024-04-27 65/week @ 2024-05-04 64/week @ 2024-05-11 45/week @ 2024-05-18 61/week @ 2024-05-25 77/week @ 2024-06-01 55/week @ 2024-06-08 76/week @ 2024-06-15 66/week @ 2024-06-22 8/week @ 2024-06-29

212 每月下载
用于 9 个crate (通过 busrt)

MIT 许可

13KB
300 代码行,不包括注释

tokio-task-pool

针对 Tokio 运行时的任务池

https://crates.io/crates/tokio-task-pool

问题

一个典型的模式

loop {
    let (socket, _) = listener.accept().await.unwrap();
    tokio::spawn(async move {
        process(socket).await;
    });
}

实际上是反模式,可能会破坏你的生产环境。

为什么?因为这个模式的行为等同于一个无界的通道。如果生产者的速率高于消费者,它会将任务洪流般地注入运行时,最终导致内存溢出。

解决方案

  • 使用工作者池代替

  • 使用任务创建,但使用信号量手动限制活动任务的数量

  • 使用这个crate,它将任务自动完成工作

提供的功能

  • 具有安全创建方法的池对象,自动限制任务数量

  • 如果设置了运行超时,任务可以自动终止,无论是全局还是针对特定任务

代码示例

简单的创建类似于 tokio::spawn,但异步,因为生产者必须被阻塞,直到池中有空的任务槽位

use std::time::Duration;
use tokio_task_pool::Pool;

#[tokio::main]
async fn main() {
    let pool = Pool::bounded(5)
        .with_spawn_timeout(Duration::from_secs(5))
        .with_run_timeout(Duration::from_secs(10));
    pool.spawn(async move {
        // do some job
    }).await.unwrap();
}

更多技巧

参考 crate 文档。

功能

  • "log" 功能可以自动记录超时任务错误(通过 log crate)

依赖

~2.4–8.5MB
~58K SLoC