patternrusttokioMajor
tokio: setting up the async runtime correctly
Viewed 0 times
tokio 1.x
tokioruntimeexecutorasyncmainblock_onspawn_blocking
Error Messages
Problem
Async functions compile fine but panic at runtime with 'no current runtime' or produce cryptic errors because the tokio runtime is not set up correctly.
Solution
Use the #[tokio::main] macro to set up the runtime, or build it manually for library code:
[dependencies]
tokio = { version = "1", features = ["full"] }// Application entrypoint — macro sets up multi-threaded runtime
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let result = fetch_data("https://example.com").await?;
println!("{}", result);
Ok(())
}
// For tests
#[tokio::test]
async fn test_something() {
let val = async_operation().await;
assert_eq!(val, 42);
}
// In library code where you need to run async from sync context
fn sync_wrapper() -> String {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async_operation())
}Why
Rust's async/await is just syntax sugar for state machines. Futures are lazy — they do nothing until polled by an executor (runtime). tokio provides the multi-threaded executor, I/O reactor, and timer driver.
Gotchas
- #[tokio::main] defaults to a multi-threaded runtime — use #[tokio::main(flavor = "current_thread")] for single-threaded
- Blocking synchronous code (file I/O, CPU work) inside async tasks starves the runtime — use tokio::task::spawn_blocking
- tokio::time::sleep is not the same as std::thread::sleep — the latter blocks the thread
Revisions (0)
No revisions yet.