4

I try to understand how node.js works and although I have read this article: When is the thread pool used? I am not sure what happens if all worker threads are busy and another async I/O operation is ready to be executed.

If I got this http://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/ article right, the event loop is blocked until a worker thread is free to take care of an additional I/O operation. This would imply that if five users tried to access a webpage simultaneously (like their profile page which lets say requires a db-query), the 5th user will be blocked until the first db-query is done and this worker thread is free again?

Community
  • 1
  • 1
Daniel
  • 874
  • 10
  • 31
  • Keep in mind that you will have to examine how your database library does its I/O. It might or might not use the nodejs thread pool. – jfriend00 Jun 15 '15 at 12:09
  • It would be helpful to me if you posted more of a complete example of what you're doing and what you have in mind. What type of web-server are you running, for instance? Briefly, what's the architecture of your multi-thread application and in what context is it being used? – Mike Robinson Jun 15 '15 at 12:17
  • I don't have anything specific in mind; I was just curious. I knew that paypal is using node and I thought every database query would be carried out in a workerthread in order not to black the main event loop. – Daniel Jun 15 '15 at 12:46

2 Answers2

4

I/O in general does not block the event loop (there are some exceptions like the crypto module currently and things like fs.*Sync() methods) and especially in the case of network I/O, the libuv thread pool is not used at all (only for things like dns (currently) and fs operations).

If your database driver is written in C++ as a node.js addon, there is a chance that it could either block the event loop (it's doing something synchronous) or it could be using the libuv thread pool. However if the database driver is only written in JavaScript, it typically uses some sort of network I/O, which as previously mentioned does not block anything and does not use the libuv thread pool.

So with your example, depending on how the database driver is implemented, all 5 users could be serviced at once. For example, MySQL at the protocol level only supports one outstanding query at a time per connection. So what most MySQL drivers for node.js will do is queue up additional queries until the current query has finished. However, it's entirely possible for a MySQL driver to internally maintain some sort of connection pool so that you have greater concurrency.

However, if each of the 5 requests were instead causing something to be from disk, then it's possible that the 5th request will have to wait until one of the other 4 fs requests have finished, due to the current default size of the libuv thread pool. This doesn't mean the event loop itself is blocked, as it can still service new incoming requests and other things, but the 5th client will just have to wait a bit longer.

mscdex
  • 104,356
  • 15
  • 192
  • 153
  • Thanks for your answer. I should have been more precise in my initial question, but you answered almost everything I wasn't sure about. I meant asynchronus operations (like mongoDB querys via mongoose). So is there any kind of queue for operations which are carried out in worker threads? – Daniel Jun 15 '15 at 12:38
  • Based on some quick googling, it seems that mongodb has a similar limit -- one outstanding query per connection. However the `mongoose` module has internal support for a connection pool (`poolSize`). There is a queue for any operations destined for the libuv thread pool. As mentioned in my answer, that includes things like DNS queries (currently) and filesystem operations. – mscdex Jun 15 '15 at 13:33
1

Is there any kind of queue for operations which are carried out in worker threads?

Yes. libuv manages this queue. It is possible for all of the worker threads to be occupied, in which case new asynchronous requests that go to the worker pool will not make progress. Note that an "asynchronous FS request" must still be completed somewhere, and will block the worker thread on which it is being handled until it completes.

James Davis
  • 848
  • 8
  • 12