futurify

Crates.iofuturify
lib.rsfuturify
version0.3.0
sourcesrc
created_at2019-09-29 23:50:56.598534
updated_at2019-11-24 13:36:51.362099
descriptionConvert your sync functions into non-blocking thread futures
homepage
repositoryhttps://github.com/robertohuertasm/futurify
max_upload_size
id168708
size14,648
Roberto Huertas (robertohuertasm)

documentation

README

Futurify

ActionsStatus Crates.io

Convert your sync functions into non-blocking thread futures.

Support for both Futures 0.1 and Futures 0.3. By default, Futures 0.3 will be used.

When to use it

This is just an example to illustrate when this library could be useful.

Imagine you're creating an actix-web API and you have and endpoint that has to execute a very long synchronous task.

Normally, most of the modern crates will provide some async variants but still there are some of them that only provide a sync implementation.

This could be problematic as this endpoint could block the main thread and avoid other endpoints from being executed.

Take a look at this code:

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()
}

If you try to get localhost:8080/blocking and then get localhost:8080, you will be able to see that you won't get any response until the blocking endpoint has returned.

With just a slight change we could get rid of this issue:

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()
}

Just wrap a closure with futurify::wrap and you'll get a futures 0.3 future ready to be polled.

Futures 0.1 support

If you need support for Futures 0.1 just import the library like this in your Cargo.toml:

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

That should do the trick!

Commit count: 5

cargo fmt