On Thu, 07 Feb 2013 19:56:13 GMT, Øivind Loe wrote:
1) I would like to have a couple 'server' threads dealing with different types of requests, e.g. 1 thread for http+websockets, one for raw sockets, ++. How would I do that? Is it enough to call the individual setup-functions in each thread and then call 'start()'?
It should be enough to create a new core.thread.Thread
and then call runEventLoop()
, setup should happen automatically in the module constructor of vibe.core.core
.
2) For a server thread waiting for incoming connections or data on existing threads, e.g. thread A. How would I asynchronously send data to thread A based on a request from another thread?
In theory this would work using the Signal
and Mutex
classes in vibe.core
. However, as it stands, they are not really suitable for multi-threading currently. I have that on the table for a while, but have been distracted by lots of other stuff. There will also be a std.concurrency
-like message passing system that would be ideal for this.
For now something that works would be to use a core.sync.mutex.Mutex
and poll in the receiver thread for new messages in a receiver queue that is protected by the mutex (DList, deque or similar). Polling can be done using a loop calling vibe.core.core.sleep(1.msecs())
between the polls.
3) For threads where the main focus is not listening for requests, but e.g. sending some data to a mongodb server. Is it possible to just call the related DB functions and continue executing code, checking back on the request at a later time if it was fulfilled? Note that I don't want this thread to be running an event-loop.
If you have no event loop running, all operations will be blocking. For any background operations the event loop is always required (or a different thread). You could do something like this, though:
void quasiThreadFunc()
{
auto task = runTask({ db.querySomthing(); });
// now do lots of blocking stuff and heavy computation causing the event
// loop to stall...
// but call getEventDriver().processEvents() periodically to keep
// the asynchronous I/O going
// check if the query is still running using task.running or
// wait for it using task.join();
}
void threadFunc()
{
runTask(&quasiThreadFunc);
runEventLoop();
}
P.S.: I take it that you really need separate threads for this because the threads are performing computations or use synchronous I/O. If that were not the case, I would just use runTask()
to acheive concurrency and not deal with threads at all. Or, if heavy computation or synchronous I/O is indeed needed, as long as task permits it, I would recommend to try to find a design that performs all I/O in a single thread and uses threads purely for the computational tasks. The computation threads could then be signaled using standard condition variable and all communication between the I/O tasks would not need to worry about threading issues, which can greatly simplify the code in some cases.