17

Perhaps somebody who implemented node.js module can explain the protocol between node.js queue processed on a single thread and a blocking IO operations that will be performed by a module.

I suspect that it goes something like this:

  1. node.js thread registers a callback in a form of a closure and saves it with some correlation id.
  2. node.js invokes a method (which should perform blocking IO) on a module and passes method parameters and correlation id to it.
  3. module method spins off a thread and blocks on IO operation.
  4. when IO operation completes, modules' thread calls back to node.js thread and passes results and correlation id to it.
  5. node.js thread finds stored callback closure by correlation id and invokes it with result returned from module.

Question 1: Is above sequence correct?

Question 2: What exactly is node.js queue? Is it the part where epoll, kqueue or IO completion port on windows is used? Is it a callback mechanism for module to notify node.js thread that some IO had finished? How does it work?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Sharas
  • 860
  • 8
  • 18
  • 1
    node simply uses libuv which is a non-blocking IO library for C. If you want to know whether libuv does any blocking calls internally in a threadpool then go read that – Raynos Dec 27 '11 at 19:17
  • 3
    If you have an hour to kill, why not let the author of Node.js himself explain why and how he built it? Highly interesting. Just Google for "ryan dahl" and "node.js" ... History of Node.js: http://www.youtube.com/watch?v=SAc0vQCC6UQ You can probably find some presentation where he goes into the details. – nisc Jan 11 '12 at 10:00

2 Answers2

9

Node.js doesn't really manage any of this quite as you speculated. It instead relies on the OSs to do most of the async IO. It uses select/epoll/kqueue depending on the operating system. "They" just put a call out and the OS calls back with a stream, chunks, etc... As far as the evented portion of it, this is built into V8, it does all the work tieing callbacks to specific events same as it does in the browser. Finally, you can look into libuv, which was written along with node and is now all maintained by Joyent. It's open source on Github so you can browse through the code if you really want the details =D

Scott
  • 1,012
  • 7
  • 14
  • Not an expert, but maybe it depends on what module you're calling. As of release 8.1, child process ultimately calls [uv_spawn in process_wrap.cc#L226](https://github.com/nodejs/node/blob/v8.1.0/src/process_wrap.cc#L226) with some explanation of how uv_spawn works [here](https://nikhilm.github.io/uvbook/processes.html#spawning-child-processes). Also see [internal/child_process.js#L292](https://github.com/nodejs/node/blob/v8.1.0/lib/internal/child_process.js#L292). – Ben Creasy Jun 11 '17 at 18:43
  • Noticed that the [libuv docs](http://docs.libuv.org/en/v1.x/design.html#file-i-o) say this: "unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on, so the current approach is to run blocking file I/O operations in a thread pool" – Ben Creasy Jun 11 '17 at 21:52
-1

I highly suspect that Node.JS goes the same route as Twisted and uses only non-blocking IO and greenlets. OS threads seem pretty inefficient for this sort of thing.

Campadrenalin
  • 243
  • 1
  • 7
  • A greenlet is a virtual thread of execution that doesn't use OS-level threads. Twisted and Gevent are among the Python libraries that use them. Greenlets generally rely on cooperative multitasking and non-blocking IO to achieve high speed and efficiency. Basically, it usually involves wrapping blocking IO functions to use non-blocking, check the result, and switch immediately to another greenlet if the socket or file isn't ready. – Campadrenalin Dec 27 '11 at 19:29