RejectedSoftware Forums

Sign up

Fundamental Confusion: Event Loop + Tasks + Functions from vibe.d

I need to write a simple TCP client and thought to give vibe.d a try. I did write a simple web application using vibe.d before and a more complicated one using boost::asio*. So I do know the event loop etc. basically work, what I don't quite understand is:

Which parts of vibe.d are actually asynchronous and which are not? There seems to be no indication in the documentation (on a per function basis), but I've looked briefly at the code and anything regarding TCP seems to go through the EventDriver, thus is asynchronous.

Now, if it's asynchronous by default, wouldn't I always need at least one task and one event loop? What happens if I call a async function outside of any task?

How does the 'download' example work? There is no event loop and no task.

import vibe.vibe;

void main()
{

auto f = openFile("test.html", FileMode.CreateTrunc);
f.write(download("http://google.com/"));

}

What if I would do

shared static this()
{
runTask({ download(something);});
runTask({ download(somethingElse); });
// use default main loop
}

Would those downloads run effectively in parallel, will the two tasks yield regularly?

I hope the post isn't as confusing as I am confused ;)

* which ended as quite the nightmare, using only callbacks and no coroutines at the time.

Re: Fundamental Confusion: Event Loop + Tasks + Functions from vibe.d

On Mon, 26 Oct 2015 16:41:50 GMT, Tobias Pankrath wrote:

I need to write a simple TCP client and thought to give vibe.d a try. I did write a simple web application using vibe.d before and a more complicated one using boost::asio*. So I do know the event loop etc. basically work, what I don't quite understand is:

Which parts of vibe.d are actually asynchronous and which are not? There seems to be no indication in the documentation (on a per function basis), but I've looked briefly at the code and anything regarding TCP seems to go through the EventDriver, thus is asynchronous.

I'd really like to have the possibility to enforce proper use of some kind of @async UDA that could be used to force the use of only synchronous code blocks. That would also solve the documentation issue, but unfortunately this isn't possible in D without resorting to additional syntax. But apart from that it would probably indeed be a good idea to start documenting all functions that potentially yield - I'll open a ticket.

Now, if it's asynchronous by default, wouldn't I always need at least one task and one event loop? What happens if I call a async function outside of any task?

How does the 'download' example work? There is no event loop and no task.

import vibe.vibe;

void main()
{
	auto f = openFile("test.html", FileMode.CreateTrunc);
	f.write(download("http://google.com/"));
}

In this case, each time a blocking command internally yields execution, a temporary event loop that just waits for a single event is started. This is basically a special mode just to support this use case.

What if I would do

shared static this()
{
  runTask({ download(something);});
  runTask({ download(somethingElse); });
  // use default main loop
}

Would those downloads run effectively in parallel, will the two tasks yield regularly?

Yes, exactly, each time a network command doesn't return a result immediately, the task will yield execution until a previously registered callback is invoked by the event loop, which in turn resumes the task.

I hope the post isn't as confusing as I am confused ;)

* which ended as quite the nightmare, using only callbacks and no coroutines at the time.

Re: Fundamental Confusion: Event Loop + Tasks + Functions from vibe.d

In this case, each time a blocking command internally yields execution, a temporary event loop that just waits for a single event is started. This is basically a special mode just to support this use case.

Thank you for the quick answer, this was the most important piece of missing information.