Foi*_*ard 0 asynchronous lazy-loading rust discord
我正在用Serenity用 Rust 编写一个不和谐的机器人。为了填充一些嵌入标头,我需要与机器人相关的信息(用户和所有者,以下称为BOT),并且我尝试使用Once_cellLazy板条箱中的结构来实现这一点。
问题是这些BOT数据只能使用 Serenity 的 Http 模块的异步函数来查询,而我正在努力使其工作。
我设置了一些斜杠命令,每个命令都有自己的处理函数。当我BOT从这些处理程序函数之一取消引用(这就是应该评估它(仅一次),对吧?)时,我的Lazy闭包在它遇到的第一个函数上阻塞.await。
另一方面,当我BOT从main(tokio async)取消引用时,它才起作用。
因此,以下代码在从特定斜杠命令处理程序 (BoxedFuture) 取消引用时打印“0,1,2,3” BOT,main但仅打印“0,1”:
use once_cell::sync::Lazy;
use serenity::{http::Http, model::user::User};
pub struct Bot {
pub user: User,
pub owner: User,
}
pub static BOT: Lazy<Bot> = Lazy::new(|| {
println!("0");
let http_client = Http::new(env!("DISCORD_BOT_TOKEN"));
futures::executor::block_on(async {
println!("1");
let user = http_client
.get_current_user()
.await
.expect("An HTTP client error occured")
.into();
println!("2");
let owner = http_client
.get_current_application_info()
.await
.expect("An HTTP client error occured")
.owner;
println!("3");
Bot { user, owner }
})
});
Run Code Online (Sandbox Code Playgroud)
谁能解释这是为什么吗?
您永远不应该在异步运行时内阻塞。永远不能。
您可以使用tokio::sync::OnceCell代替once_cell:
pub async fn get_bot() -> &'static Bot {
static BOT: tokio::sync::OnceCell<Bot> = tokio::sync::OnceCell::const_new();
BOT.get_or_init(|| async {
println!("0");
let http_client = Http::new(env!("DISCORD_BOT_TOKEN"));
println!("1");
let user = http_client
.get_current_user()
.await
.expect("An HTTP client error occured")
.into();
println!("2");
let owner = http_client
.get_current_application_info()
.await
.expect("An HTTP client error occured")
.owner;
println!("3");
Bot { user, owner }
})
.await
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1059 次 |
| 最近记录: |