0

I have a sample code with an express server with a REST endpoint that perfroms a fs.readFile operation. I understand that the operation is asynchronous and does not block the main thread running as single threaded process. But I want clarification on what happens when there are hundreds of requests to the Node.js server and requests are queued in I/O.Is there any kind of multithreading for the file reading operation here that happens in the background at the I/O level? or is that just a single threaded operation too? if so would it not be a bottleneck for large number of requests?

  • 2
    https://codeburst.io/how-node-js-single-thread-mechanism-work-understanding-event-loop-in-nodejs-230f7440b0ea can be helpful. – vibhor1997a Dec 08 '18 at 17:21

2 Answers2

3

File I/O in node.js uses a thread pool (for native code associated with file operations). There is a queue for pending file I/O operations and each thread in the thread pool takes an event from the queue, process it, finishes it, fires the completion event and then grabs the next pending file I/O operation from the queue and processes it.

From the Javascript side of things, this is all non-blocking. When you call one of the asynchronous file operations, it gets handed off to the file I/O sub-system and immediately returns control back to the JS engine to run other JS. Sometime later when the internal system finishes the file I/O operation, and event is added to the node.js event queue and when whatever JS was running at the time finishes and gets to the next event in the node.js event queue, then the callback associated with the completion of that asynchronous file operation is called and the JS associated with it runs.

I have a sample code with an express server with a REST endpoint that performs a fs.readFile operation. I understand that the operation is asynchronous and does not block the main thread running as single threaded process.

That is correct.

But I want clarification on what happens when there are hundreds of requests to the Node.js server and requests are queued in I/O.Is there any kind of multithreading for the file reading operation here that happens in the background at the I/O level?

Hundreds of requests would stack up in the internal file I/O queue and they'd be served N at a time by the N threads in the thread pool used for internal native code for file I/O.

or is that just a single threaded operation too? if so would it not be a bottleneck for large number of requests?

It's N threads at a time (the number of threads in the thread pool). Yes, this would be a bottleneck. Doing hundreds of file requests at the same time is always going to be some sort of bottleneck regardless of how it's programmed because at the lowest level, the disk can only seek to one location at a time and read one part of the disk at a time. The size of the thread pool inside of node.js is controllable, but if all your disk I/O requests are going to the same underlying disk, you will reach a point where you don't gain efficiency by adding more threads that are all contending for the same read/write head on the disk.

If you're looking to understand more about how the node.js event loop and other sub-systems work, there are lots of helpful articles on the topic:

How Node.Js Single Thread mechanism Work ? Understanding Event Loop in NodeJs

Handling IO — NodeJS Event Loop Part 4

How node.js event loop works

The Node.js Event Loop, Timers, and process.nextTick()

libuv documentation on the thread pool and customizing it

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Can this be summarised as: "I/O is queued in main thread and processed outside of the main thread. How exactly that queue is processed is up to the OS" ? – nicholaswmin Dec 08 '18 at 18:37
  • 1
    @Pranavkirtani - Please make sure you've see all the recent additions to my answer. I hope you will find this a fairly comprehensive answer to your question with lots of external references to learn more. If not, let me know what you still need help in understanding. – jfriend00 Dec 08 '18 at 18:54
  • 1
    @NikKyriakides - All types of I/O are not treated the same. Network I/O uses the underlying asynchronous model in the OS so it does not use threads. Disk I/O does use a thread pool in libuv which then uses the underlying OS to carry out the actual file operation. The file I/O queue itself is in libuv, not in the OS. It's libuv (part of node.js) that pulls an item from the queue, hands it to a thread in the thread pool and then lets the OS handle the actual file operation in that thread. – jfriend00 Dec 08 '18 at 18:56
  • Thank you; Doesn't libuv also handle network I/O for Node.js? – nicholaswmin Dec 08 '18 at 18:59
  • @NikKyriakides - Yes. libuv is part of the OS level abstraction that node.js uses. See http://docs.libuv.org/en/v1.x/design.html for more info. – jfriend00 Dec 08 '18 at 19:01
  • @jfriend00:Hey thanks for the info very comprehensive – Pranav kirtani Dec 09 '18 at 06:02
1

The cloudburst.io link in the comments is a great in depth explanation.

The short version is that the node process itself is single threaded, but it relies on the OS to handle I/O tasks and similar, keeping track of pending callbacks with file handles.

What this means is that the answer to your question is"more or less", because it assumes that the OS has the supporting features. Most do, so it's a safe bet, but not all for all IO ops are guaranteed to.

Paul
  • 35,689
  • 11
  • 93
  • 122