新 Tokio + 对旧 hyper 的依赖

New Tokio + dependency with older hyper

我正在使用 tokio 0.2.x 但我需要使用依赖于 hyper 0.12.35 的依赖项。

这会导致 SpawnError { is_shutdown: true } 恐慌。

我设法以一种孤立的方式重现了这个:

cargo.toml

[dependencies]
tokio = { version = "0.2.11", features = ["full"] }
hyper = "0.12.35"
futures = "0.1.29"

这是代码:

use hyper::rt;
use futures::future as future01;

fn future_01() -> impl future01::Future<Item = (), Error = ()> {
    future01::ok(())
}

#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    rt::spawn(future_01());
    Ok(())
}

我的依赖项将此 rt::spawn 深入到实现中,因此我无法修改它。

理想情况下,我想将 rt::spawn 使用的默认执行程序设置为与 tokio::main 提供的相同。这可能吗?

Ideally, I would like to set the default executor used by rt::spawn to be the same as the one that tokio::main provides. Is that possible?

不可能,tokio = "0.2.11" 只有实现 std::future::Future 才能生成任务,您无法使用 futures = "0.1.29" 创建这些任务,您需要使用版本0.3.x 或者您需要使用 compat 功能将旧期货转换为新期货 ().

This result in SpawnError { is_shutdown: true } panics.

您正在使用的 Hyper 在内部使用 tokio 运行time,这是 Tokio 的旧版本(它也在您的 Cargo.lock 中使用较新版本)。在 Tokio 中,如果没有启动 运行time 就不可能生成任务,所以你需要像这样生成你的任务:

fn main() -> Result<(), std::io::Error> {
    rt::run(future_01());
    Ok(())
}

警告:

如果您仍想使用 2 个不同的 运行时间,一个来自新版本,另一个来自旧版本,请不要像下面那样使用它!您需要 运行 它们在单独的线程中。

//don't use this code!
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    rt::run(future_01());
    Ok(())
}

因为 main 是异步函数而 rt::run 是阻塞函数( )