I think it is quite correct. But there are some nuances, actually writes and reads are non-blocking. Libuv will queue everything until the OS will tell it that data could be read/written. So the most *blocking* thing here is a user callbacks, and that means that everything is up to you! ;)
On Wed, Jan 22, 2014 at 9:06 PM, <[email protected]> wrote: > Ok, after reading more on of the source code, watching the Google Tech > Talk on Node.js and considering your answers, this is a rough attemp to > make sense of what happens in libuv when you have, for instance, a HTTP > request asking for a file (assume Node.js using libuv): > > 1) The default event loop listening to TCP connections will run the > callback for accepting the connection. > > 2) The connection is accepted, and the OS notifies that there's data to > be read in the socket. > > [default loop dealing with other requests...] > > 3) The request (data) will be read in the main thread up to a certain > limit to avoid starvation (32 iterations, as in `uv__read`). > > 4) The user callback will be called inside this libuv callback, still > in the main thread. It will parse the request, and upon finding that it > should read a file, will call the FS abstraction asking for that file. > If we assume Node.js here, this callback means a V8 invocation running > in the main thread, and no other requests can be served in the mean > time. > > 5) The call to read a file will spawn asynchronous work by calling > `uv__work_submit`. The task will be performed in another thread, and > `uv_sync_asend` will send the file contents through a socket (pipe?) > when it's done. > > [async request running and default loop dealing with other requests...] > > 6) The file contents will be received by a watcher in the main thread, > and the default event loop will read it all and call the user callback > with the file contents. No requests can be served while we're doing > that. > > 7) The user callback (still running in the main thread) will write the > response to the client. No requests can be served while we're doing > that. > > > I think I may have mistaken some parts, especially in step 4 and in the > parts where requests can't be served in steps 6 and 7. I'm assuming a > small request and a small file. > > Is this more or less correct or did I get it all wrong? > > > Thank you for the patience :) > Allan > > On Wednesday, January 22, 2014 9:18:06 AM UTC-2, Fedor Indutny wrote: >> >> I mean using the same TCP server fd in multiple threads each with it's >> own libuv loop. You'll still need to send the `uv_tcp_t` server handle >> to other threads using IPC pipe (see `uv_pipe_open`). >> >> On Wed, Jan 22, 2014 at 3:14 PM, <[email protected]> wrote: >> > What do you mean by listening on the same fd? >> > >> > I have used the other approach when using libevent (one event loop >> > giving >> > control of the fds to other event loops in other threads). >> > >> > On Wednesday, January 22, 2014 9:11:29 AM UTC-2, Fedor Indutny wrote: >> >> >> >> Hello again! >> >> >> >> Sorry for not answering all of your questions. >> >> >> >> libuv is a single-threaded library, and everything, except, >> >> uv_work_cb's are executed in the same thread, where uv_run() "runs". >> >> There are at least two ways, how you could make libuv-based app use >> >> all available CPUs: load-balancing incoming sockets via IPC pipes to >> >> child process or worker threads (each with it's own libuv loop) or >> >> listening on the same fd. >> >> >> >> Node.js was using latter approach up until v0.11 that will become v0.12 >> >> soon. >> >> >> >> Cheers, >> >> Fedor. >> >> >> >> On Wed, Jan 22, 2014 at 3:02 PM, <[email protected]> wrote: >> >> > Thank you for the answers! I used libevent previously, so I was >> >> > confused about the different nature of libuv. >> >> > >> >> > I took a look at the NodeJS source code, and how it uses libuv, and >> >> > one >> >> > question remains. >> >> > >> >> > Is the default event loop/main thread used for everything? Assuming a >> >> > request comes in, this thread alone will: get notified about the >> >> > event, >> >> > read the data, run the callback, and then write back a response? All >> >> > of >> >> > this on a single thread, for any number of requests? >> >> > >> >> > I read parts of the NodeJS code, but I couldn't find anything that >> >> > points to any thread parallelism (except from debugging). It seems >> >> > that >> >> > even uv_queue_work is not even being called much. >> >> > >> >> > >> >> > If this question is too specific, let me know and I'll ask it in the >> >> > NodeJS mailing list. >> >> > >> >> > >> >> > Allan >> >> > >> >> > On Friday, January 17, 2014 4:35:40 PM UTC-2, Fedor Indutny wrote: >> >> >> >> >> >> Hello! >> >> >> >> >> >> You should not call anything except `uv_async_send()` from another >> >> >> thread. Many functions are inserting stuff into loop's linked lists >> >> >> and the list itself is not thread-safe (not even talking about many >> >> >> other internals). >> >> >> >> >> >> `uv_async_send()` indeed writes to one end of the pipe, and libuv is >> >> >> listening on the other end of the pipe, and interrupts loop and >> >> >> invokes callback when receives data. >> >> >> >> >> >> As a way to return data back from uv_work_cb - you could set and >> >> >> change req.data safely inside worker thread, it'll be available in >> >> >> uv_work_done_cb. >> >> >> >> >> >> Cheers, >> >> >> Fedor. >> >> >> >> >> >> On Fri, Jan 17, 2014 at 6:19 PM, <[email protected]> wrote: >> >> >> > Hi, >> >> >> > >> >> >> > I've been curious about how libuv works internally regarding >> >> >> > thread >> >> >> > communication. >> >> >> > >> >> >> > This is what I understand: >> >> >> > There's a single thread running uv_run. If I spawn some work to be >> >> >> > done >> >> >> > in another thread I'm supposed to use uv_queue_work. The way to >> >> >> > send >> >> >> > the results of this work back to the main thread is through >> >> >> > uv_async_send (which is the only thread-safe function in libuv). >> >> >> > >> >> >> > This is what I want to do: >> >> >> > Start listening on a TCP socket, accept incoming connections in >> >> >> > the >> >> >> > default loop, and wait for data to be available for reading (using >> >> >> > uv_read_start). When it's available for reading, I'd put the work >> >> >> > (socket reading) in the queue (with uv_queue_work), and the >> >> >> > callback >> >> >> > for this would run in another thread, reading the data and >> >> >> > performing >> >> >> > some work based on it, which may involve writing data back to this >> >> >> > or >> >> >> > any other socket. >> >> >> > >> >> >> > So, my questions related to this are: >> >> >> > - Is this possible to do? If I call uv_read_start and uv_write in >> >> >> > another thread, can this cause trouble, because they should have >> >> >> > been >> >> >> > called in the default loop? >> >> >> > >> >> >> > - If uv_read_start and uv_write should be called in the default >> >> >> > loop, >> >> >> > then the main thread will be responsible for reading and writing >> >> >> > all >> >> >> > data, right? Wouldn't this impact performance? How does NodeJS >> >> >> > deal >> >> >> > with this? >> >> >> > >> >> >> > - How does uv_async_send work? From a quick glance at the source >> >> >> > code, >> >> >> > I suspect it sends data in a file descriptor, which will be read >> >> >> > in >> >> >> > the >> >> >> > default loop. Is this what is happening? >> >> >> > >> >> >> > >> >> >> > Allan >> >> >> > >> >> >> > -- >> >> >> > You received this message because you are subscribed to the Google >> >> >> > Groups >> >> >> > "libuv" group. >> >> >> > To unsubscribe from this group and stop receiving emails from it, >> >> >> > send >> >> >> > an >> >> >> > email to [email protected]. >> >> >> > To post to this group, send email to [email protected]. >> >> >> > Visit this group at http://groups.google.com/group/libuv. >> >> >> > For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups "libuv" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/libuv. For more options, visit https://groups.google.com/groups/opt_out.
