#future #non-blocking #spawn #threading #background

未来化

将您的同步函数转换为非阻塞线程future

4个版本 (2个破坏性更新)

0.3.0 2019年11月24日
0.2.0 2019年9月30日
0.1.1 2019年9月30日
0.1.0 2019年9月29日

#1623异步

MIT 许可证

14KB
128

未来化

ActionsStatus Crates.io

将您的同步函数转换为非阻塞线程future。

支持 Futures 0.1Futures 0.3。默认情况下,将使用 Futures 0.3

何时使用它

以下是一个示例,说明何时可以使用此库。

想象您正在创建一个 actix-web API,并且您有一个端点必须执行一个非常长的同步任务。

通常,大多数现代crate都会提供一些 async 变体,但还有一些只提供 sync 实现的。

这可能会成为问题,因为此端点可能会阻塞主线程,从而避免其他端点被执行。

看看这段代码

use actix_web::{web, App, HttpServer, Responder};
use std::time::Duration;

async fn index_async() -> impl Responder {
    futures::future::ready("Hello world").await
}

async fn index_async_blocking() -> impl Responder {
    futures::future::lazy(|_| {
        std::thread::sleep(Duration::from_secs(5));
        "Hello blocking world"
    })
    .await
}

fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to_async(index_async))
            .route("/blocking", web::get().to_async(index_async_blocking))
    })
    .workers(1)
    .bind("localhost:8080")?
    .run()
}

如果您尝试获取 localhost:8080/blocking 然后获取 localhost:8080,您将能够看到,直到 blocking 端点返回,您将不会收到任何响应。

只需稍作修改,我们就可以解决这个问题

async fn index_async_non_blocking() -> impl Responder {
    futurify::wrap(|| {
        std::thread::sleep(Duration::from_secs(5));
        "Hello non blocking world"
    })
}

fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index_async))
            .route("/blocking", web::get().to(index_async_blocking))
            .route("/non-blocking", web::get().to(index_async_non_blocking))
    })
    .workers(1)
    .bind("localhost:8080")?
    .run()
}

只需使用 futurify::wrap 将闭包包装起来,您就可以获得一个 futures 0.3 future,准备好进行轮询。

支持Futures 0.1

如果您需要支持 Futures 0.1,只需在您的 Cargo.toml 中按如下方式导入库

futurify = { version = "0.3", features = "futures_01", default-features = false }

这样应该就可以了!

依赖关系

~135KB