Am 24.10.2013 13:19, schrieb Stephan Dilly:

On Thu, 24 Oct 2013 06:46:05 GMT, Sönke Ludwig wrote:

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

Thanks for you reply, I don't get the stuff you are doing with this aa of Tasks. Why is that necessary ?

That was just for the case that different tasks have different trigger
conditions. If all are waiting for the same "dataPending" condition,
that is fine, too.

What is working for me now is the following solution, but it turns up more questsions :D

class SockJsConnection
{
	TaskMutex mutex;
	TaskCondition condition;
	bool dataPending;
	
	this()
	{
		mutex = new TaskMutex;
		condition = new TaskCondition(mutex);
	}
	
	void handleLongPoll(HTTPServerRequest req, HTTPServerResponse res)
	{
		synchronized (mutex) {
			condition.wait(10.seconds);
		}
		
		if (dataPending) {
			// write timeout response
		} else {
			// write normal response
		}
	}
	
	void write()
	{
		dataPending = true;
		condition.notifyAll();
	}
}

Why do I need to synchronize over the mutex to wait ? I thought vibe.d is using fibers and async io for concurrency ? Can I configure how it scales over multiple threads ?

That's the standard protocol for condition variables, which ensures that
checking the condition happens atomically. This avoids that a
notification is missed while checking the condition. The following shows
how threads (or tasks, if I/O is involved) may get interleaved by the
scheduler so that a notification is missed and thread 1 waits longer
than expected.

thread 1                        thread 2
check if data available -> no
                                 set data available to yes
                                 notify
wait for notification

A similar condition can occur in your code if dataPending is already
true before condition.wait() is called.

So you should at least use

synchronized (mutex) {
	if (!dataPending)
		condition.wait(10.seconds);
}

As long as no threads are involved, and no I/O happens between checking
the condition and waiting (or between setting dataPending and
notifyAll()) the mutex is not strictly necessary, but should
multi-threading ever be needed for performance scaling, it's good to
have the correct code already there.

What's the difference between condition.notify() and condition.notifyAll() - for me the code seems to be exactly the same ;)

The current implementation is sub optimal, but the idea is that
notify() will only wake up one task/thread that waits for the
condition, while notifyAll() wakes up all of them. So notify is
useful e.g. when multiple worker threads are waiting on a single
condition, but only one work item is added to the queue.

Last but not least: Is there a irc channel for D ?
We are seeing a realistic chance to use vibe.d in our company for a server backend, but we would like to be able to shorten the communication routes as much as possible ;)

There is no IRC channel for vibe.d AFAIK. I'm usually pretty responsive
on the forums, though (IRC wouldn't really be better in that regard),
but currently I'm a bit overloaded with communication.