On Wed, 23 Oct 2013 08:32:18 GMT, Stephan Dilly wrote:

Hi guys,
I am just investigating how to implement long polling with vibe.

Since I just started using vibe.d I am totally new to the concepts of fibers and the vibe.d API.

But from what I found I thought using a ManualEvent to wait in a http handleRequest until a timeout happens or another fiber triggers an emit on the ManualEvent and then returning the response should do the trick.
The problem is, that when the timeout happens or the emit is triggerd from another fiber (another GET request that is) then the response is not valid anymore.

Any ideas ? Is my whole concept wrong ?

Regards

I'm not 100% sure what the issue is, but I'd use a TaskCondition instead of a raw ManualEvent to avoid the possibility for accidental race conditions. Just to be on the same page, this is about what I would do:

// possibly __gshared
TaskMutex s_mutex;
TaskCondition s_condition;
bool[Task] s_tasks;

// possibly shared static this
static this()
{
    s_mutex = new TaskMutex;
    s_condition = new TaskCondition;
}

void handleLongPoll(HTTPServerRequest req, HTTPServerResponse res)
{
    auto task = Task.getThis();
    s_tasks[task] = false;
    auto timeout = Clock.currTime(UTC()) + 10.seconds;
    bool timed_out = false;
    synchronized (s_mutex) {
        while (!s_tasks[task]) {
            auto tm = Clock.currTime(UTC());
            timed_out = tm >= timeout;
            if (timed_out) break;
            s_condition.wait(timeout - tm);
        }
        s_tasks.remove(task);
    }
    if (timed_out) {
        // write timeout response
    } else {
        // write normal response
    }
}

void onHandleEvent()
{
    synchronized (s_mutex) {
        foreach (t, ref triggered; s_tasks)
            triggered = true;
    }
    s_condition.notifyAll();
}

Or do you mean that the response is not valid anymore because a connection timeout occurred somewhere? I think such a timeout should only occur in the client, in which case it should be OK. The client would simple have to start another poll request and the server request handler would simply throw an exception and terminate.