首页 > 解决方案 > 为什么第二个 await 不会在 tokio::spawn 上被调用?

问题描述

我有以下使用 sqlx 连接到数据库的函数):

async fn testConnect() -> anyhow::Result<PgPool> {
    delay_for(Duration::from_millis(3000)).await;
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&"database_connection_string")
        .await?;

    Ok(pool)
}

我在 tokio 运行时运行它:

let mut threaded_rt = runtime::Builder::new()
    .threaded_scheduler()
    .enable_all()
    .build()
    .unwrap();
threaded_rt.block_on(future::lazy(move |_| {
    let handle = tokio::spawn(testConnect());
    return handle;
}));

delay_forinside之后的任何代码testConnect都不会被执行。为什么会这样,我怎样才能让两者都await运行?

如果我删除这delay_for行代码,数据库连接代码将按预期运行。

标签: rust

解决方案


我怀疑会发生以下情况。这类似于启动后台工作线程并退出而不加入它。

  • 您在 tokio 上生成任务并返回句柄
  • block_on驱动 tokio reactor 一会儿,这对于正常连接来说已经足够了,但不足以让延迟到期
  • 不再驱动反应堆,所以生成任务的结果只是被丢弃并且程序退出

如果是这样,您可以通过threaded_rt.block_on(testConnect())直接调用来修复它,该spawn()部分似乎完全没有意义。


推荐阅读