Runtime panic because of older Tokio runtime in Rust Playground

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

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.