Skip to content

Block on async code or await blocking code

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

across-travel/blocking

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

blocking

Build Rustc version License Cargo Documentation Chat

Block on async code or await blocking code.

To convert async to blocking, block on async code with block_on(), block_on!, or BlockOn.

To convert blocking to async, unblock blocking code with unblock(), unblock!, or Unblock.

Thread pool

Sometimes there's no way to avoid blocking I/O in async programs. 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 thread pool provided by this crate. The pool dynamically spawns and stops threads depending on the current number of running I/O jobs.

Note that there is a limit on the number of active threads. Once that limit is hit, a running job has to finish before others get a chance to run. When a thread is idle, it waits for the next job or shuts down after a certain timeout.

Examples

Await a blocking file read with unblock!:

use blocking::{block_on, unblock};
use std::{fs, io};

block_on(async {
    let contents = unblock!(fs::read_to_string("file.txt"))?;
    println!("{}", contents);
    io::Result::Ok(())
});

Read a file and pipe its contents to stdout:

use blocking::{block_on, Unblock};
use std::fs::File;
use std::io::{self, stdout};

block_on(async {
    let input = Unblock::new(File::open("file.txt")?);
    let mut output = Unblock::new(stdout());

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

Iterate over the contents of a directory:

use blocking::{block_on, Unblock};
use futures::prelude::*;
use std::{fs, io};

block_on(async {
    let mut dir = Unblock::new(fs::read_dir(".")?);
    while let Some(item) = dir.next().await {
        println!("{}", item?.file_name().to_string_lossy());
    }
    io::Result::Ok(())
});

Convert a stream into an iterator:

use blocking::BlockOn;
use futures::stream;

let stream = stream::once(async { 7 });
let mut iter = BlockOn::new(Box::pin(stream));

assert_eq!(iter.next(), Some(7));
assert_eq!(iter.next(), None);

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Block on async code or await blocking code

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Rust 100.0%