Asynchronous 是否使用async/await实现静态?
阿萨拉穆·阿莱库姆 我是个新手。我正在使用mongodb和异步运行时(tokio)Asynchronous 是否使用async/await实现静态?,asynchronous,rust,Asynchronous,Rust,阿萨拉穆·阿莱库姆 我是个新手。我正在使用mongodb和异步运行时(tokio) 我想全局初始化mongo客户端,所以我使用了一个名为的板条箱。问题是mongodb异步连接,而现在lazy\u static不支持async关键字 使用mongodb::Client; 异步的{ 让client=client::with_uri_str(&env_var(“MONGO_URL”)).wait.unwrap(); } 那么如何全局初始化客户机对象呢 相关的: 如果使用新的运行时,并且首先在现有
我想全局初始化mongo客户端,所以我使用了一个名为的板条箱。问题是mongodb异步连接,而现在lazy\u static不支持
async
关键字
使用mongodb::Client;
异步的{
让client=client::with_uri_str(&env_var(“MONGO_URL”)).wait.unwrap();
}
那么如何全局初始化客户机对象呢
相关的:
如果使用新的运行时,并且首先在现有运行时的上下文中使用惰性静态,如本例所示:
use lazy_static::lazy_static;
use mongodb::Client;
lazy_static! {
static ref CLIENT: Client = {
tokio::runtime::Runtime::new().unwrap().block_on(async {
let uri = std::env::var("MONGO_URL").unwrap();
let client = Client::with_uri_str(&uri).await.unwrap();
client
})
};
}
#[tokio::main]
async fn main() {
let _db = CLIENT.database("local");
}
您将看到提到的错误:
线程“main”处于恐慌状态,无法从运行时内启动运行时。发生这种情况的原因是,当线程用于驱动异步任务时,函数(如“block_on”)试图阻止当前线程。C:\Users\kmdreko\.cargo\registry\src\github.com-1ec6299db9ec823\tokio-1.6.1\src\runtime\enter.rs:39:9
您可以通过使用不同的运行时(futures
vstokio
vsasync std
)来规避此问题,但这并不理想,因为它仍然会阻塞底层运行时
解决这一问题的一个相对简单的方法是不要尝试懒洋洋地去做,并在main
中立即初始化它。这样,您就可以直接利用异步运行时,而不用担心在其他地方需要异步运行时:
use mongodb::Client;
use once_cell::sync::OnceCell;
static CLIENT: OnceCell<Client> = OnceCell::new();
#[tokio::main]
async fn main() {
let uri = std::env::var("MONGO_URL").unwrap();
let client = Client::with_uri_str(&uri).await.unwrap();
CLIENT.set(client).unwrap();
let _db = CLIENT.get().unwrap().database("local");
}
这假设客户端的所有或几乎所有使用都是在异步上下文中进行的。如果初始化时使用tokio提供的block_on
函数而不是wait
可以阻止,那么等待结果就会完成任务。你链接的StackOverflow Q&A有两个建议:要么block_on
或者使用OnceCell
。为什么答案不充分?据我所知,您正在寻找的是一种类似于
lazy\u static的OnceCell
包装器代码>,但它是用异步
块而不是闭包初始化的。然而,在这种情况下,似乎mongodb
库的编码很差,而with_uri_str
方法实际上不需要是异步的,所以我只需要使用block_on
。多亏了您的时间,但使用您的方法创建新问题,我仍然在寻找答案,最低限度是@Coder-256,@Aiden4,@kmdreko,我试过OnceCell
,futures::executor::block_on
,tokio::runtime::runtime::new
等等,它们都会产生新的问题,比如线程“tokio runtime worker”恐慌于“无法从另一个executor内部执行LocalPool
executor:enterror”等等。。。
use async_once::AsyncOnce;
use lazy_static::lazy_static;
use mongodb::Client;
lazy_static! {
static ref CLIENT: AsyncOnce<Client> = AsyncOnce::new(async {
let uri = std::env::var("MONGO_URL").unwrap();
let client = Client::with_uri_str(&uri).await.unwrap();
client
});
}
#[tokio::main]
async fn main() {
let _db = CLIENT.get().await.database("local");
}