On Sun, 20 Jan 2013 08:50:36 GMT, Brad Anderson wrote:

I have two request handlers, one of which waits around looking to see if the other one was called (or eventually times out).

I tried something like this but it doesn't work for some reason:

(...)

I think that timers are broken for some reason in the libevent back end right now. I just noticed this yesterday, but didn't have the chance yet to investigate it; will do as soon as possible.

I saw the `Signal class that says it's for communication between fibers but I don't see a way of having the wait()` timeout.

What's a good way to go about doing something like this?

If timers would be working, however, combining a Signal and a Timer would be possible using a low level rawYield() (this will wait until any event arrives from one of the acquired objects). Some kind of abstraction for this kind of task swould be great, as it occurs quite frequently; just need to figure out a clean and general way...

Until then, something like this ought to work:

bool open_cmd = false;
Signal signal;

static this()
{
    signal = createSignal();
}

void command(HttpServerRequest req, HttpServerResponse res)
{
    open_cmd = true;
    signal.emit();
}

void wait(HttpServerRequest req, HttpServerResponse res)
{
    auto tm = setTimer(dur!"seconds"(15), null);
    tm.acquire();
    scope(exit) tm.release();

    signal.acquire();
    scope(exit) signal.release();

    while(!open && tm.pending) rawYield();

    if( !open ){
        res.writeBody("Timed out");
        return;
    }

    open_cmd = false;
    res.writeBody("Received command.");
}

Disclaimer: Don't try to use this with enableWorkerThreads() though, since Signal and Mutex in their current form were just an early attempt to make things work, but they lack proper thread-safety. Better versions of this and some other parts of the API are in the works, but it's still difficult in some places to statically guarantee thread-safety without compromising on the API (i.e. without it getting verbose, unintuitive or too restricted).