multithreadingasynchronousrustwarp

Trouble passing mpsc sync channel in warp handler


I'm new to rust and encountered an issue while building an API with warp. I'm trying to pass some requests to another thread with a channel(trying to avoid using arc/mutex). Still, I noticed that when I pass an mpsc::sync::Sender to a warp handler, I get this error.

"std::sync::mpsc::Sender cannot be shared between threads safely"

and

"the trait Sync is not implemented for `std::sync::mpsc::Sender"

Can someone lead me in the right direction?

use std::sync::mpsc::Sender;

pub async fn init_server(run_tx: Sender<Packet>) {
    let store = Store::new();
    let store_filter = warp::any().map(move || store.clone());

    let run_tx_filter = warp::any().map(move || run_tx.clone());
    let update_item = warp::get()
        .and(warp::path("v1"))
        .and(warp::path("auth"))
        .and(warp::path::end())
        .and(post_json())
        .and(store_filter.clone())

        .and(run_tx_filter.clone()) //where I'm trying to send "Sender"
        .and_then(request_token);


    let routes = update_item;

    println!("HTTP server started on port 8080");
    warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
}
pub async fn request_token(
    req: TokenRequest,
    store: Store,
    run_tx: Sender<Packet>,
) -> Result<impl warp::Reply, warp::Rejection> {
    let (tmp_tx, tmp_rx) = std::sync::mpsc::channel();

    run_tx
        .send(Packet::IsPlayerLoggedIn(req.address, tmp_tx))
        .unwrap();

    let logged_in = tmp_rx.recv().unwrap();

    if logged_in {
        return Ok(warp::reply::with_status(
            "Already logged in",
            http::StatusCode::BAD_REQUEST,
        ));
    }
    Ok(warp::reply::with_status("some token", http::StatusCode::OK))
}

I've looked through some of the examples for warp, and was also wondering what are some good resources to get knowledgable of the crate. Thank you!


Solution

  • This is because you're using std::sync::mpsc::Sender. std::sync implements !Sync, so you won't be able to use that. You don't want to use that anyway since it's blocking.

    When you use async functionality in rust, you need to provide a runtime for it. The good news is that warp runs on the tokio runtime, so you should have access to tokio::sync::mpsc If you take a look at that link, the Sender for that mpsc implementation implements Sync and Send so it's safe to share across threads.

    TLDR:

    Use tokio::sync::mpsc instead of std::sync::mpsc and this won't be an issue.