Reputation: 943
In warp (rust), how can I pass a std::sync::mpsc::Sender<T>
to my business handlers? The following codes complains that std::sync::mpsc::Sender<T>
is not Sync
.
I understand that I possibly could wrap my_sender
with something like Arc<RwLock<Sender<T>>>
, but that doesn't seem right, since the purpose of channel is to enable inter-threads communication.
Do I have to wrap the Sender<T>
, or there is a better way to do this?
use std;
use warp::{self, Filter};
fn with_sender<T: Send + Sync>(
sender: std::sync::mpsc::Sender<T>,
) -> impl Filter<Extract = (std::sync::mpsc::Sender<T>,), Error = std::convert::Infallible> + Clone
{
warp::any().map(move || sender.clone())
}
// later in main():
let (my_sender, my_receiver) = std::sync::mpsc::channel::<MySyncAndSendType>();
let routes = (warp::get()
.and(warp::path!("some" / "path"))
.map(my_handlers::handler_1)
.map(turn_result_to_json)
.or(warp::post()
.and(warp::path!("some" / "other" / "path"))
.and(warp::multipart::form().max_length(10 * 1024 * 1024))
.and(with_sender(my_sender.clone()))
// -------------------------------------------------------------------------
// -------> I need my_sender in the function my_handlers::handler_2 <-------
.and_then(|form, my_sender| async move {
Ok::<_, Infallible>(my_handlers::handler_2(form, my_sender).await)
})
.map(turn_result_to_json)));
warp::serve(routes).run(([127, 0, 0, 1], 1234)).await;
Upvotes: 1
Views: 1041
Reputation: 58805
Sender
is not Sync
, so it cannot be shared, but it is Send
, so you can move
it into the async task.
The problem with your code is that the closure is capturing its environment by reference, even though the async
block inside is move
. You should just need to make the closure move
too:
.and_then(move |form, my_sender| async move {
Ok::<_, Infallible>(my_handlers::handler_2(form, my_sender).await)
})
Upvotes: 1