我有一个项目需要使用 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
,因为这意味着再次将所有内容重新包装为同步。
答案 0 :(得分:0)
您可以将 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 代码的其余部分之间获取数据。
在新线程中加入尽可能多的客户端和错误处理,以限制跨线程的对话,以防出现性能瓶颈。