Am 07.02.2014 20:29, schrieb Sean Kelly:

One thing I'm not entirely sure of is how vibe.d handles outbound connections. Like say I get a request from the user. This request comes across some client connection and so is backed by its own fiber. Now what if I need to issue a request to some other service while processing this transaction? Any IO on the secondary connection needs to yield and return to that client connection's stack. I imagine vibe.d manages this automatically, but it's a bit further than I've gotten in my own experimentation. I suppose an alternative would be to spawn the outbound connection in its own fiber and use message passing to mediate between them. Then the client connection would block on receive() until that secondary request completes and sends its response.

Each fiber can (usually) only have one connection active at the same
time, that's true. However, a connection only "owned" by a single
fiber/task while it is in one of its blocking methods, such as read or
write. When nothing is done on the connection, it is not owned by any
fiber and any events in that time will more or less be ignored.

The only exception here is that for any accepted incoming connection a
task is created to invoke the handler callback and this task will
automatically close the connection once the callback returns. But this
just to avoid dangling connections when uncaught exceptions occur and is
not really related to the ownership in the event processing sense.

BTW a nice property of (non-worker) tasks is that since they run in the
same thread, it's often possible to save the overhead of message passing
completely and simply use stack/thread local vars. For example to do
multiple outgoing requests in parallel:

void showClusterStats(HTTPServerRequest req, HTTPServerResponse res)
{
     Task[] tasks;
     string[] stats;
     foreach (node; m_cluster) {
         tasks ~= runTask({
             requestHTTP(node.url ~ "/status",
                 (scope req) {}
                 (scope res) {
                     // safely access variable of the outer scope
                     stats ~= res.bodyReader.readAllUTF8();
                 }
             );
         });
     }

     // wait for all tasks to finish
     foreach (t; tasks) t.join();

     // write response
     res.writeBody(...);
}