rouille icon indicating copy to clipboard operation
rouille copied to clipboard

Why does `handler` need to be `Sync`?

Open Reconcyl opened this issue 6 years ago • 2 comments

I have a situation where I want to pass a sender to the request handler:

use std::sync::mpsc::Sender;
let tx: Sender<Foo> = get_sender();
rouille::start_server(ADDR, move |req| handle(req, tx.clone()));

Unfortunately, this doesn't work because unlike std::thread::spawn, start_server(addr, handler) requires that handler is Sync.

Why is this the case? Is there any way to get around it without resorting to a Mutex?

Reconcyl avatar Feb 14 '19 08:02 Reconcyl

I actually ran into this exact case today!

Rouille uses a thread pool internally, which means that multiple requests could be happening simultaneously. That concurrent access means that any types you access from your handler need to be Sync!

LPGhatguy avatar Feb 15 '19 00:02 LPGhatguy

Hi, I ran into this issue too. The problem, from what I can tell, is that there is no way to actually clone a Sender such that you can move it into one of the threads that will process a request.

Often in cases like these, you can get around it by cloning then moving in an extra block:

{
    let tx = chan.clone();
    move |req| {
        // use tx
     }
}

But even this doesn't appear to work. There should be a way to share Sender clones to request handlers. Is there any workaround in place here except for adding an extra Mutex on the Sender?

The send method only takes Sender by &self so it feels very unfortunate and almost like a bug to have to stick it in a Mutex.

leshow avatar May 20 '20 13:05 leshow