AFAIK, Rust Playground uses Tokio version 1.29.1 but I'm seeing the error saying that 1.x
must be used.
Here's the minimal code.
use core::time::Duration;
use tokio::time::sleep;
fn main() {
let rt = tokio::runtime::Runtime::new().unwrap();
println!("good night");
rt.block_on(sleep(Duration::from_millis(10000)));
println!("good morning");
}
see: Rust Playground
Here's the error:
there is no reactor running, must be called from the context of a Tokio 1.x runtime
I've read other threads with the topic (and also googled), but I couldn't find an article explaining about this. What am I missing for using Tokio's sleep or block_on
?
I thought that block_on
helps to call .await
on async
function from non-async
. So I don't have a good idea what's going on here.
I guess the problem is that the call to sleep
(and not only the sleeping itself) must happen inside the async context. Your code can be made to work by replacing the problematic line with rt.block_on(async { sleep(Duration::from_millis(10000)).await });
- playground.
4 Likes
this should work.
println!("good night");
+ let _guard = rt.enter();
rt.block_on(sleep(Duration::from_millis(10000)));
println!("good morning");
explanation: the panic has nothing to do with block_on()
, but instead happened inside sleep()
. when sleep()
constructs the Future
, it need to register an entry into the reactor's timer list. if the current thread has not entered the runtime, it doesn't have a reactor to contact, so it panics.
fn main() {
let rt = tokio::runtime::Runtime::new().unwrap();
// try comment out this line, and you'll get a panic
let _guard = rt.enter();
sleep(Duration::from_millis(10000));
}
4 Likes