Hi all,
Just trying to get my head around async/.await
in a small project and how best to manage them.
Using the latest actix-web 2.0 version that is async by default, I've got a main function that builds a server in this manner:
HttpServer::new(move || {
App::new()
// ...
.service(web::resource("/contact").route(web::post().to(process_contact_request)))
})
.bind("127.0.0.1:8000")?
.run()
.await
with a handler looking like
async fn process_contact_request(
contact_request: web::Json<ContactRequest>,
req: HttpRequest,
kv: web::Data<KVStore>,
) -> Result<HttpResponse, Error> {
// Do a bunch of checks
// ...
if *captcha == contact.challenge {
// Logging, other processing
// ...
// Send off another async request to a separate server.
report_contact(
&contact,
&referer,
req.connection_info().remote().unwrap_or("Unknown"),
)
.await?;
// Response to frontend
Ok(HttpResponse::Ok().finish())
} else {
Ok(HttpResponse::BadRequest().body("Invalid challenge value"))
}
}
What I'm struggling with here is how to treat this report_contact
call.
Since it will take some time to process, calling .await
right here is blocking the Ok
response.
I'd like to be able to return the Ok
and await the result afterward. In fact, since report_contact(...) -> Result<(), Error>
, I'm only interested in error propagation/handling; there is no need to process some return value of this call.
My best guess would be to use a wrap_fn call for the web::resource
handler and send off the report_contact
request at the middleware level, but can't really figure out how to invoke it at that level, since I need to pass it a few processed variables as you can see.
Is this the right way forward, or have I missed something in the way one should handle async code correctly in this context?