微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从异步调用的 Rust Postgres同步驱动程序导致“无法从运行时内启动运行时”

如何解决从异步调用的 Rust Postgres同步驱动程序导致“无法从运行时内启动运行时”

我有一个项目需要使用 postgres 同步驱动程序(第三方库需要同步回调)并且它公开了一个 GRPC API。

不幸的是,rust-postgres 做了一个 block_on 嵌套在 #[tokio::main]

最小的重现是:

use postgres::{Client,NoTls};

#[tokio::main]
async fn main() {
    let _client = Client::connect("host=localhost dbname=template1 user=postgres",NoTls).unwrap();
}

具有依赖项:

tokio = { version = "1.6.1",features = ["rt-multi-thread","macros"] }
postgres = "0.19.1"

我收到错误

'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.'

sql 查询性能并不重要,我可以很好地阻止它们。我宁愿不切换到 tokio-postgres,因为这意味着再次将所有内容重新包装为同步。

解决方法

您可以将 rust-postgres 代码生成到它自己的独立线程上。

use postgres::{Client,NoTls};

#[tokio::main]
async fn main() {
    std::thread::spawn(|| {
        let _client = Client::connect("host=localhost dbname=template1 user=postgres",NoTls).unwrap();
    });
}

然后通过标准方法设置线程间通信,例如tokio::sync::mpsc 消息传递,以在数据库驱动程序和 Rust 代码的其余部分之间获取数据。

在新线程中加入尽可能多的客户端和错误处理,以限制跨线程的对话,以防出现性能瓶颈。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。