Rust
Tokio runtime
Start a runtime with #[tokio::main].
The Tokio runtime
tokio is Rust's most common asynchronous runtime: it offers a thread pool, task scheduler, timers and async network/file APIs. The #[tokio::main] attribute makes main async:
// Cargo.toml: tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() {
let veri = indir("https://..").await;
}
// roughly expands to:
fn main() {
tokio::runtime::Runtime::new().unwrap().block_on(async {
let veri = indir("https://..").await;
})
}
So the macro calls a much more advanced version of the block_on we wrote in the previous group.
Runtime flavours
Tokio offers two schedulers: multi-threaded (the default, tasks spread across CPU cores) and single-threaded (current_thread, for tests and small tools):
#[tokio::main(flavor = "current_thread")]
async fn main() { .. }
#[tokio::test]
async fn async_test() {
assert_eq!(hesapla().await, 42);
}
#[tokio::test] sets up a separate runtime for each test.
Exercise What the macro expands to
Imitate the expansion of #[tokio::main]: write the block_on executor, and let async fn baslat() -> &'static str return "sunucu başladı". In main, print the result of block_on(async { baslat().await }).
Show example solution
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
fn block_on<F: Future>(f: F) -> F::Output {
let mut f = pin!(f);
let mut cx = Context::from_waker(Waker::noop());
loop {
if let Poll::Ready(v) = f.as_mut().poll(&mut cx) {
return v;
}
}
}
async fn baslat() -> &'static str {
"sunucu başladı"
}
fn main() {
let mesaj = block_on(async { baslat().await });
println!("{}", mesaj);
}
Test yourself
-
Why is calling <code>std::thread::sleep</code> in an async task a problem?
- There's no problem
- It blocks the runtime's thread; other tasks on the same thread wait too
- It doesn't compile
- It sleeps longer
Show answer
It blocks the runtime's thread; other tasks on the same thread wait too — In async code use tokio::time::sleep(..).await; for blocking work there is tokio::task::spawn_blocking.
-
Runtime entry
#[tokio::____]
async fn main() {
println!("başladı");
}
Show answer
#[tokio::main]
async fn main() {
println!("başladı");
}
-
Tool and role
- #[tokio::main]
- Async main
- #[tokio::test]
- Async test
- current_thread
- Single thread
- spawn_blocking
- Blocking work
Next lesson: spawn