Why Tokio runtimes aren't independent?

AFAIK there's no special threadpool crate for std futures (like there was futures-cpupool for v0.1), and the current practice is to use a tokio threaded runtime and block_in_place on it.

I want to separate my CPU-heavy async threadpool from my normal I/O-bound threadpool, so that heavy tasks can't starve network or cause latency. I've tried simply creating two runtimes, but tokio is incredibly annoying with the error:

Cannot start a runtime from within a runtime. This happens because a function (like block_on) attempted to block the current thread while the thread is being used to drive asynchronous tasks.

AFAIK I'm not starting a runtime from within a runtime (both runtimes are created in main, which isn't async), and I'm not blocking inside block_on — the inner .spawn is non-blocking.

So why tokio doesn't like this?

fn main() {
    let mut rt = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap();
    let second_rt = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap();

    rt.block_on(rt.spawn(async move {
        second_rt.spawn(async {}).await
    }))
    .unwrap().unwrap();
}

How can I use two runtimes together, without running into "Cannot start a runtime from within a runtime" error?

Afaik the main reason of the global runtime is to allow tokio::spawn(), which mimics signature of the std::thread::spawn().

Sorry, I don't follow that reply. Can I somehow explain to tokio I don't want them global? Why does specific_runtime.spawn() care about its context?

That appears to be a bug. Calling spawn inside another runtime should be fine. For the record, it works if you use a Handle to spawn it.

fn main() {
    let mut rt = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap();
    let matching_rt = tokio::runtime::Builder::new().threaded_scheduler().build().unwrap();

    let handle = matching_rt.handle().clone();

    rt.block_on(rt.spawn(async move {
        handle.spawn(async {}).await
    }))
    .unwrap().unwrap();
}
3 Likes

That's a great find. I've opened a ticket about this curiosity: "Cannot start a runtime from within a runtime." false positive? · Issue #2529 · tokio-rs/tokio · GitHub

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.