Why does calling tokio::spawn result in the panic “SpawnError { is_shutdown: true }”?

此生再无相见时 提交于 2019-12-05 11:09:43

The documentation for tokio::spawn states:

This function will panic if the default executor is not set or if spawning onto the default executor returns an error.

Effectively, this means that tokio::spawn should only be called from inside a call to tokio::run.

Since you have only a single future to execute, you might as well just pass it directly to tokio::run. If you had multiple futures, then you can make make use of future::lazy to construct a lazily-evaluated future that will call spawn when it eventually runs:

use std::time::*;
use tokio::prelude::*; // 0.1.14

fn main() {
    tokio::run(futures::lazy(|| {
        tokio::spawn(wait_one_sec().map(|_| println!("One")));
        tokio::spawn(wait_one_sec().map(|_| println!("Two")));
        Ok(())
    }));
}

fn wait_one_sec() -> impl Future<Item = (), Error = ()> {
    tokio::timer::Delay::new(Instant::now() + Duration::from_secs(1))
        .map(drop)
        .map_err(|e| panic!("{:?}", e))
}

Note that if you forget the futures::lazy then you will get the same error. This is because the arguments to functions are evaluated eagerly, which means that the call to tokio::spawn happens first, causing the same sequence of events.

use std::sync::mpsc;

I think it's highly doubtful that you want to use the standard libraries channels, as they are not async-aware and thus will block — a very bad thing in async code.

Instead, you probably want futures::sync::mpsc.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!