为什么我在使用futures crate中的block_on时会出现“在Tokio运行时上未运行”而导致恐慌?

20

我正在使用Elasticsearch博客文章中有关其新的crate的示例代码,但无法按预期使其正常工作。线程出现了panic:thread 'main' panicked at 'not currently running on the Tokio runtime.'

Tokio运行时是什么,如何配置它以及为什么必须要配置它?

use futures::executor::block_on;

async elastic_search_example() -> Result<(), Box<dyn Error>> {
    let index_response = client
        .index(IndexParts::IndexId("tweets", "1"))
        .body(json!({
            "user": "kimchy",
            "post_date": "2009-11-15T00:00:00Z",
            "message": "Trying out Elasticsearch, so far so good?"
        }))
        .refresh(Refresh::WaitFor)
        .send()
        .await?;
    if !index_response.status_code().is_success() {
        panic!("indexing document failed")
    }
    let index_response = client
        .index(IndexParts::IndexId("tweets", "2"))
        .body(json!({
            "user": "forloop",
            "post_date": "2020-01-08T00:00:00Z",
            "message": "Indexing with the rust client, yeah!"
        }))
        .refresh(Refresh::WaitFor)
        .send()
        .await?;
    if !index_response.status_code().is_success() {
        panic!("indexing document failed")
    }
}

fn main() {
    block_on(elastic_search_example());
}

你从哪里导入 block_on 函数? - Cerberus
它来自于 futures::executor::block_on - Miranda Abbasi
2个回答

18

看起来Elasticsearch的crate在内部使用Tokio,因此您必须也使用它来匹配他们的假设。

在查找文档中的block_on函数时,我得到了这个。所以,您的main应该像这样:

use tokio::runtime::Runtime;

fn main() {
    Runtime::new()
        .expect("Failed to create Tokio runtime")
        .block_on(elastic_search_example());
}

或者你可以使用属性宏main 函数本身变为异步函数,这将为您生成运行时创建和 block_on 调用:

#[tokio::main]
async fn main() {
    elastic_search_example().await;
}

这解释了很多。谢谢。 - Miranda Abbasi
使用第二种方法无法编译,会出现以下两个错误:error[E0277]: main 具有无效的返回类型 impl futures::Future --> src\main.rs:110:17 | 110 | async fn main() { | ^ main 只能返回实现了 Termination 的类型 | = help: 考虑使用 ()Resulterror[E0752]: main 函数不允许是 async --> src\main.rs:110:1 | 110 | async fn main() { | ^^^^^^^^^^^^^^^ main 函数不允许是 async - Dani P.
请提出新问题,并附上您的真实代码和真实错误信息,因为您可能没有使用与示例完全相同的代码或未显示完整的错误信息。 - Cerberus

7
当我使用tokio::run(自tokio版本0.1)与使用tokio02(自tokio版本0.2)内部的crate(例如reqwest)时,我遇到了同样的错误。 起初,我只是使用futures03::compatstd::future::Future更改为futures01::future::Future,以使其编译通过。但在运行之后,我得到了和你一模一样的错误。

解决方案:

添加tokio-compat解决了我的问题。


了解更多关于tokio compat的内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接