On 2013-12-06 4:34 PM, Etienne Cimon wrote:

On 2013-12-06 1:06 PM, Sergei Nosov wrote:

Hi!

I have 2 general questions on the implementation. Maybe someone could
give brief answers or some links with explanation?

  1. vibe.d claims to have asynchronous I/O via fibers. As I understand
    it - this means the flow looks something like this. When we're
    handling a request we come to a certain point, where we need to e.g.
    query a record from DB. We issue an asynchronous request and call smth
    like yield, not to waste CPU time. Someone wakes us later, we check
    for the status of the request, and proceed if it's ready, or yield
    again otherwise.

So, it brings the question - in that case - who is responsible for
calling yield? I assume if I'm not calling it myself, it should be
called by the vibe.d functions. So, if I want to read from file - I
shouldn't use readText, but should use some vibe.d yield-aware
alternative. Is that the case?

  1. Suppose, I have a class instance with state - e.g. a cached value
    of something. In each request I check if the value should be updated,
    possibly update it and proceed using this value. How I should make it
    work in vibe.d? If I create a class instance in shared static<br>this(), then as I understand, the instance is shared among all of the
    threads, so if I use the cached value without synchronization - it's a
    race. Is that so? How can I avoid it?

1)
ctx.core.yieldForEvent is called automatically in
vibe/core/drivers/libevent2_tcp.d at a lot of locations after reading or
writing data to or from buffers.

The fiber is resumed when ctx.core.resumeTask is called after a callback
is triggered from libevent2 here:

buffereventsetcb(bufevent, &onSocketRead, &onSocketWrite,
&onSocketEvent, client_ctx);

If you need to run routines that take a lot of CPU cycles, you can call
yield() every now and then to make sure other requests aren't left out
while this operation runs.

2)

You should place variables shared between fibers outside the scope of
shared static this()

Fibers don't race with each other, they are called sequentially in an
event loop as they are paused and resumed. Only threads are exposed to
data races, but by default, vibe.d runs on one thread only. Regardless,
D's variables are all thread-local by default as well. You can use
gshared storage specifier if you want to share globally, this is the
only possibility of there being a data race. It's recommended to use D's
synchronized specifier to lock global methods in a mutex if you need to
consult a
gshared object.

Read more here: http://dlang.org/migrate-to-shared.html

If you want to read from a file, you should use

http://vibed.org/api/vibe.core.file/openFile

It takes care of yield() by itself.