[][src]Crate blocking

An executor for isolating blocking I/O in async programs.

Sometimes there's no way to avoid blocking I/O. Consider files or stdin, which have weak async support on modern operating systems. While IOCP, AIO, and io_uring are possible solutions, they're not always available or ideal.

Since blocking is not allowed inside futures, we must move blocking I/O onto a special executor provided by this crate. On this executor, futures are allowed to "cheat" and block without any restrictions. The executor dynamically spawns and stops threads depending on the current number of running futures.

Note that there is a limit on the number of active threads. Once that limit is hit, a running task has to complete or yield before other tasks get a chance to continue running. When a thread is idle, it waits for the next task or shuts down after a certain timeout.

Examples

Spawn a blocking future with Blocking::spawn():

use blocking::Blocking;
use std::fs;

let contents = Blocking::spawn(async { fs::read_to_string("file.txt") }).await?;

Or do the same with the blocking! macro:

use blocking::blocking;
use std::fs;

let contents = blocking!(fs::read_to_string("file.txt"))?;

Read a file and pipe its contents to stdout:

use blocking::Blocking;
use std::fs::File;
use std::io::stdout;

let input = Blocking::new(File::open("file.txt")?);
let mut output = Blocking::new(stdout());

futures::io::copy(input, &mut output).await?;

Iterate over the contents of a directory:

use blocking::Blocking;
use futures::prelude::*;
use std::fs;

let mut dir = Blocking::new(fs::read_dir(".")?);

while let Some(item) = dir.next().await {
    println!("{}", item?.file_name().to_string_lossy());
}

Macros

blocking

Spawns blocking I/O onto a thread.

Structs

Blocking

Async I/O that runs on a thread.