On 17/10/16 19:41, Gonzalo Diethelm wrote:
First post, libuv newbie.
Hi and welcome to libuv then!
I am trying to understand how a multi-threaded web server would fit in
the libuv design. This is how I envision it, but I have some questions.
The main thread would run the HTTP accept loop, and I would expect each
connection request to be handled to a worker in the thread pool. Each
thread in the worker pool will also be doing I/O (think running a query
against MySQL), and will somehow pass the results back to the main thread.
After reading a bit here and there, I would think this is one way to do
this with libuv:
1. Main thread runs default loop and handles all the HTTP traffic.
Whenever it gets an HTTP request, it puts it in a thread-safe queue and
does a notify_all to awake one random thread in the pool; all of these
threads would be waiting on the queue.
2. One worker thread awakes, dequeues pending work from the queue and
runs it. I guess each thread has its own libuv loop, to handle the I/O
needed to go to MySQL / read a file / etc.
If each thread is a uv loop, then you could send the connection where
the request came from from one loop to another using uv_write2. That
way the job of the "acceptor loop" would only be accepting and
3. Once the request has been processed, the worker thread notifies the
main thread that the response is ready and tries to read the next
pending request from the queue; iterate.
4. The main thread sends the response back to the HTTP client and closes
Now, there's some hand waving here, and I am not sure if what I'm
describing is the proper / correct / best / possible way to do this with
libuv. Some specific questions:
1. Is using a thread-safe queue a good match for libuv? If libuv
provides something like this, I have not been able to find it, and that
makes me doubt this would be the libuv way.
For certain scenarios such a construct would be useful, we don't provide
it though. Have a loop at http://concurrencykit.org/
2. Is it possible / advisable to have multiple threads in a process,
each handling I/O with its own libuv loop? I guess yes.
Yep. Nginx (which doesn't use libuv) uses a similar model.
3. How would the worker threads notify the main thread that a response
is ready? Would they use an async handle for this? If yes, can they all
use the same async handle, or would each worker require their own async
handle plugged to the main thread loop? But if they all share the same
async handle, how does the main thread know which connection this
response should be sent to?
They don't need to! They can handle the connection themselves and send
the response without having the main thread do it.
In case it helps, I created a multi-threaded HTTP server prototype to
try out some stuff here: https://github.com/saghul/uttp It currently
uses SO_REUSEPORT for kernel level connection balancing in Linux and the
NOTES file https://github.com/saghul/uttp/blob/master/NOTES contains the
other strategies I was going to try but never found the time :-)
I hope you find it useful.
Saúl Ibarra Corretgé
You received this message because you are subscribed to the Google Groups
To unsubscribe from this group and stop receiving emails from it, send an email
To post to this group, send email to email@example.com.
Visit this group at https://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.