RejectedSoftware Forums

Sign up

Communicating between request handlers

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:

__gshared bool open_cmd = false;

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

void wait(HttpServerRequest req, HttpServerResponse res)
{
	StopWatch sw;
	sw.start();
	while(!open_cmd)
	{
		Thread.sleep(dur!"msec"(25));

		if(sw.peek().seconds > 15)
		{
			res.writeBody("Timed out", "text/plain");
			return;
		}
	}

	open_cmd = false;
	res.writeBody("Recieved command", "text/plain");
}

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?

Re: Communicating between request handlers

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).

Re: Communicating between request handlers

On Sun, 20 Jan 2013 09:55:41 GMT, Sönke Ludwig wrote:

Until then, something like this ought to work:

(...)

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).

That worked perfectly. Thank you. I realize now why my version wasn't working. There was no yield to allow the other handler to proceed. This appears to be even better too because it isn't polling so it'll save my CPU even more work while being completely responsive.

You said timers were broken but this timed out fine. Is that just in HEAD? I'm using the D apt repo by Gordi so maybe they are working fine in the version he has up.

Re: Communicating between request handlers

Am 20.01.2013 22:39, schrieb Brad Anderson:

On Sun, 20 Jan 2013 09:55:41 GMT, Sönke Ludwig wrote:

Until then, something like this ought to work:

(...)

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).

That worked perfectly. Thank you. I realize now why my version wasn't working. There was no yield
to allow the other handler to proceed. This appears to be even better too because it isn't polling
so it'll save my CPU even more work while being completely responsive.

Oh, of course! I completely overlooked that it was Thread.sleep and not vibe.core.core.sleep!

You said timers were broken but this timed out fine. Is that just in HEAD? I'm using the D apt
repo by Gordi so maybe they are working fine in the version he has up.

It's very much possible that it's HEAD or even something with my specific application. I'll check
that out further today.

Re: Communicating between request handlers

It's very much possible that it's HEAD or even something with my specific application. I'll check
that out further today.

It turns out that it is indeed something specific to the application. In isolated examples it works just fine.