Moving Between Sync and Async Rust
Here's a handy cheat sheet for moving between sync and async Rust when using the tokio
and/or smol
runtimes.
tokio
ecosystem
- async to sync: tokio::runtime::Runtime::block_on
- This is what the
tokio::main
procedural macro uses - There's also tokio::runtime::Handle::block_on if you already have a runtime
- This is what the
- sync to async: tokio::task::spawn_blocking
Async{Read,Write,Seek}
to{Read,Write,Seek}
: tokio_util::io::SyncIoBridge{Read,Write,Seek}
toAsync{Read,Write,Seek}
: I couldn't find anything (tokio
has a solution, but it's private)Stream
toIterator
: futures_lite::stream::block_onIterator
toStream
: tokio_stream::iter or futures_lite::stream::iter
smol
ecosystem
The smol
crate just re-exports other smaller crates.
- async to sync: smol::block_on / async_io::block_on
- sync to async: smol::unblock / blocking::unblock
Async{Read,Write,Seek}
to{Read,Write,Seek}
: smol::io::BlockOn / futures_lite::io::BlockOn{Read,Write,Seek}
toAsync{Read,Write,Seek}
: smol::Unblock / blocking::UnblockStream
toIterator
: smol::stream::block_on / futures_lite::stream::block_onIterator
toStream
: smol::stream::iter / futures_lite::stream::iter
Compat
You can use things from the smol
ecosystem with tokio
, or vice versa, using one of these:
smol
and tokio
both use the same Stream
trait from futures-core
.