Actix Actor 调用异步函数(HTTP 获取请求)
Actix Actor calling an async function (HTTP get request)
我有一个定期运行的 actor。
它一直有效,直到我尝试使用 reqwest
添加 HTTP 请求
pub struct Scheduler;
impl actix::actor::Actor for Scheduler {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Context<Self>) {
ctx.run_interval(Duration::from_secs(60), move |this, ctx| { this.announce(ctx, EVENT_NONE); });
}
}
impl Scheduler {
fn announce(&self, _ctx: &mut Context<Self>, event: &str) {
//...
let mut client = reqwest::blocking::Client::new().get("http://127.0.0.1:10080");
let res = client.send();
//...
}
}
但是我有以下错误:Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context. /home/me/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/blocking/shutdown.rs:51:21
根据消息我认为我应该使用 async 但我没有找到正确的实现。你能帮帮我吗?
提前致谢
我终于找到了 2 个解决方案:
解决方案 1
pub struct Scheduler;
impl actix::actor::Actor for Scheduler {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Context<Self>) {
ctx.run_interval(Duration::from_secs(60), move |this, ctx| { this.announce(ctx, EVENT_NONE); });
}
}
impl Scheduler {
fn announce(&self, ctx: &mut Context<Self>, event: &str) {
//...
self.send_announce(ctx, url, id); //outside the announce function because it is in a loop
//...
}
fn send_announce(&self, _ctx: &mut Context<Self>, url:String, id: u32) {
actix_web::rt::spawn(async move {
let client = reqwest::Client::builder().build().expect("Cannot build web client");
let res = client.get(&url).send().await;
if res.is_ok() {
info!("It works!");
}
}
}
}
我不知道这是否是最好的方法,但它确实有效
解决方案 2
是使用ureq作为使用阻塞I/O的HTTP客户端,我可以调用ctx.run_later
。
一切都可以留在announce()
功能
我有一个定期运行的 actor。 它一直有效,直到我尝试使用 reqwest
添加 HTTP 请求pub struct Scheduler;
impl actix::actor::Actor for Scheduler {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Context<Self>) {
ctx.run_interval(Duration::from_secs(60), move |this, ctx| { this.announce(ctx, EVENT_NONE); });
}
}
impl Scheduler {
fn announce(&self, _ctx: &mut Context<Self>, event: &str) {
//...
let mut client = reqwest::blocking::Client::new().get("http://127.0.0.1:10080");
let res = client.send();
//...
}
}
但是我有以下错误:Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context. /home/me/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/blocking/shutdown.rs:51:21
根据消息我认为我应该使用 async 但我没有找到正确的实现。你能帮帮我吗?
提前致谢
我终于找到了 2 个解决方案:
解决方案 1
pub struct Scheduler;
impl actix::actor::Actor for Scheduler {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Context<Self>) {
ctx.run_interval(Duration::from_secs(60), move |this, ctx| { this.announce(ctx, EVENT_NONE); });
}
}
impl Scheduler {
fn announce(&self, ctx: &mut Context<Self>, event: &str) {
//...
self.send_announce(ctx, url, id); //outside the announce function because it is in a loop
//...
}
fn send_announce(&self, _ctx: &mut Context<Self>, url:String, id: u32) {
actix_web::rt::spawn(async move {
let client = reqwest::Client::builder().build().expect("Cannot build web client");
let res = client.get(&url).send().await;
if res.is_ok() {
info!("It works!");
}
}
}
}
我不知道这是否是最好的方法,但它确实有效
解决方案 2
是使用ureq作为使用阻塞I/O的HTTP客户端,我可以调用ctx.run_later
。
一切都可以留在announce()
功能