I'm implementing the http listener with rust hyper, I wondering how can I separate the response from the handle_request(). Here is my code snippet.
#[tokio::main]
async fn main() -> Result<()> {
//...//
tokio::spawn(process_data(rx.clone(), processor_args, tokenizer.clone()));
let addr = ([172, 17, 0, 4], 6006).into();
let cookie_jar = CookieJar::new();
let make_svc = make_service_fn(|_conn| {
let cookie_jar = cookie_jar.clone();
let vec_queue = vec_queue.clone();
let tx = tx.clone();
let tokenizer = tokenizer.clone();
async move {
let handle_request_task = tokio::task::spawn(async move {
service_fn(move |req| {
handle_request(req, cookie_jar.clone(), tx.clone(), vec_queue.clone(), tokenizer.clone())
})
});
core::result::Result::Ok::<_, hyper::Error>(handle_request_task.await.expect("failed to spawn handle_request task"))
}
});
}
async fn handle_request(
req: Request<Body>,
mut cookie_jar: CookieJar,
tx: Sender<IdsWithToken, i32>,
vec_queue: Arc<Mutex<VecDeque<IdWithMessage>>>,
mut tokenizer: Tokenizer,
) -> Result<Response<Body>, anyhow::Error> {
//...//
let request_message = IdsWithToken {
session_id: session_id.clone(),
token: token.clone(),
};
println!("request_message: {:?}", request_message);
let _ = tx.send(request_message.clone(), 0).await;
if let Some(final_response) = process_response_from_queue(vec_queue.clone(), request_message.session_id.clone()).await {
Ok(Response::new(Body::from(format!(
"Data from priority queue: {}",
final_response.message
))))
} else {
Ok(Response::new(Body::from(
"No data available in the priority queue",
)))
}
}
At now, handle_request() receiving the request of clients and returning the response to client. But I want to return nothing at handle_request(), I just want to return the response at another thread like below.
tokio::spawn(response_worker(/*...*/));
// I want to return the response of request at response_worker()
I think service_fn() of hyper must need Result<Response<Body>, _>. Then, is there any other way that separate the request and response?