4

In order to dive into more complex concepts about Node.js, I am doing some research to make sure I understand the principles about the language and the basic building blocks it´s build upon.

As far as I´m concerned, Node.js relies in the reactor pattern to process each incoming request. This algorithm is based in the Event Demultiplexer algorithm. The second one is in charge of processing the request operation and it´s resources and then, once the operation is finished, it adds the 'result' to the Event Queue. After this process, the Event Loop is now in charge of executing the Handlers for each event.

As a single threaded process, I´m struggling to understand how does the Event demultiplexer handle all the incoming operations if the event loop is managing all the event queue tasks in parallel...

I´ve found this in the Node.js documentation:

Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed. We'll explain this in further detail later in this topic.

Does this mean that the Event Demultiplexer tasks are not handled by Node and that Node just gets the result in order to add it to the Event Queue? Doesn´t that mean that Node is not single threaded?

I've found some useful graphics on the web that clearly explain the path that each request follows, but It´s really hard to find some explaining the actual timing in which the thread processes each one.

Luis Orbaiceta
  • 443
  • 4
  • 15
  • 2
    Normally, there's one event loop per execution context. In order to utilize multiple CPU cores, the [cluster](https://nodejs.org/api/cluster.html#cluster_how_it_works) module is used to fork additional processing loops. Also, node is single threaded in the user code. Whenever you call a library function, its internals can do anything, even spawn threads as long as the result is put back in the event loop that is processed single threaded by your user code. – Wiktor Zychla Sep 16 '20 at 15:31
  • I found this really helpful talk in case someone is interested https://youtu.be/zphcsoSJMvM – Luis Orbaiceta Sep 19 '20 at 13:21

1 Answers1

2

In node.js, it runs your Javascript in a single thread (assuming we're not talking about worker threads or clustering). But, many asynchronous operations in the node.js built-in library such as file I/O or some crypto operations use their own threads to accomplish their task. So, when you call an asynchronous operations such as fs.open() to open a file, it transitions to native code, grabs a thread from an internal thread pool and that thread goes about opening the file. The fs.open() function then returns back to your Javascript (while the thread continues in the background). Sometime later when it finishes its task, the internal thread inserts an event into the nodejs event queue and when nodejs has cycles to check the event queue, it will find that event and run the Javascript callback associated with it to provide the asynchronous result back to your Javascript.

So, even though threads may be involved, your Javascript is all still single threaded through the event loop.

So, nodejs does use native code threads for some internal native code operations. Other things like networking and timers are implemented without threads.

Then if I send a request to fetch data from a database in Node, how does the Event Demultiplexer process It? Does the main thread stop the event loop to handle that operation and then resumes after the event handler is queued?

These terms like "Event Demultiplexor" are things you are applying to node.js. They are not something that node.js uses at all so I'm not entirely sure what you're asking.

Node.js runs one event at a time. It has no interrupt-driven abilities. So, it runs one event until that event returns control back to the event loop (by issuing a return from the callback that started everything). Now, the original event may not be complete - it may be doing something asynchronous that will trigger another event to announce completion, but it has finished running Javascript for now and has returned control back to the event loop.

When an incoming Fetch request (which is just an incoming http request) arrives at the server, it is first queued by the OS. Then, when the event loop has a chance to see it, it is added to the node.js event queue and is served in FIFO order when other events that were before it are done processing. Now, the nodejs event loop is not as simple as a single event queue. It actually has several different queues for different types of work and has priorities for what gets to run first, but at the simplest level, you can start out thinking of it as a single FIFO queue. And, nothing is ever interrupted.

Pull an event out of the event queue, run the Javascript callback associated with it. When that callback returns back to the event loop, get the next event and do the same.

Events may be added to the event queue either by native code threads (like might be done with file I/O or some crypto operations) or via some polling mechanisms built into the event loop as part of the event loop cycle it checks for certain things that are ready to run (as with networking and timers).

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Then if I send a request to fetch data from a database in Node, how does the Event Demultiplexer process It? Does the main thread stop the event loop to handle that operation and then resumes after the event handler is queued? – Luis Orbaiceta Sep 16 '20 at 17:01
  • @LuisOrbaiceta - See what I added to my answer. It would be better if you used the terms that nodejs uses to describe itself rather than your own terms since the rest of us don't really know exactly what your own terms (like "Event Demultiplexor") mean in this context since that's not a nodejs term. – jfriend00 Sep 16 '20 at 17:15
  • I read about that term in the reactor pattern explanation that Mario Casciaro gives in his 'Node.Js design Patterns' book https://miro.medium.com/max/1582/1*MABVZQvtz5jkv4Fh23kzRg.png – Luis Orbaiceta Sep 16 '20 at 17:44
  • 1
    @LuisOrbaiceta - Well, there is no thing I've ever heard of called an event multiplexor in node.js so that is apparently a term the author of that article applied. I'm not sure where that article got that from. There are multiple event queues (for different types of events) and an event loop that cycles through different queues in a specific order and with specific priorities deciding what pending event in a queue to process next. – jfriend00 Sep 16 '20 at 20:42
  • But as far as i'm concerned the most important building block of Node is Libuv which is built based in the reactor pattern that has an synchronous event demultiplexer to handle all the non-blocking system I/O – Luis Orbaiceta Sep 16 '20 at 21:15