Node.js Basic Architecture

What is Node.js and Why do we use Node ?

Mayank Gupta
TechnoFunnel
7 min readMar 11, 2015

--

TechnoFunnel presents another article to explain the Architecture of Node. It a JavaScript based Server Side Language. The main feature of Node.js are:

  1. Event Driven Architecture
  2. Non Blocking I/O Model
  3. Asynchronous by Default

The following is the description as per the Official Node Page:

“Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.”

What is Node.js used for?

Node is centered around fixing the following problems:

1. Expensive I/O Operations

There are many time consuming tasks while rendering or working with a Web Request, following are some of the time consuming tasks:

  • Accessing File System
  • Access Database for Information
  • Accessing APIs
  • Accessing System Information

Lets First Analyze Traditional Approach

Lots of Thread Processing time is wasted while waiting for such I/O Operations. Lets assume a scenario where a single network request needs to access the data from the Database, access some file information and need to look for some system specific information before returning the response.

In the following scenario, a single thread would be designated to process the each request. This request contains access to Database, File System and Network Information. Following is the series to execution process:

  1. The thread goes to Database to make a query, the query requires 500ms to be processed, meanwhile the main thread will be waiting for the database request to be processed.
  2. Once the database request is processed, the thread will proceed to access the file system which is an expensive I/O process, lets assume that the I/O process consumes 300ms, the thread will again enter in waiting mode for I?O request to be complete before proceeding further.
  3. Once the I/O request is complete, we need to access the system Information (Lets assume Disk Space), this request need to access the OS details and will consume some time to fetch the information. Meanwhile the main thread is again waiting for System Information to be retrieved.

While each expensive I/O request, Database Query and OS Information is fetch, the main thread assigned for the request is waiting for these operations to complete. This model leads to lot of wastage to thread potential to process data since it is in waiting mode for majority of time rather than doing some processing.

One Request One Thread Architecture is Expensive

Lets Understand it, with the help of some scenario…

Consider an example of Restaurant who is trying hard to impress their customers with premium services…

  1. Hotel with the capacity of 50 Tables decides to hire 50 Waiters to Cater to each of the table individually. Whenever a new customer enters the hotel, a individual Waiter is assigned to each table.
  2. The customer enters the restaurant and takes time to look for the menu and decide what to order, meanwhile the waiter keeps on waiting for customer to complete a time consuming task of deciding the order to be placed. The waiter in this case is in waiting mode, doing nothing.
  3. Once the order is decided, the waiter takes the order to the chef for preparation. The Chef will consume another 15 minutes for processing the order, meanwhile the Waiter is idle again, waiting for the food preparation
  4. Once the food is prepared, the Waiter brings the food to the customer for Consumption, the customer starts eating the food. Meanwhile the Waiter is waiting for the customer to finish eating the order.
  5. Once the customer is done eating, the waiter takes off the cutlery back to Kitchen and process the Bill, the bill is presented to the customer. Once the customer is gone, this waiter is now available to serve some other table.

In the entire above process, there is inefficiency involved, the waiter just like the main thread keeps on waiting for any time consuming task to complete. During this wait time the productivity of this resource (Waiter) is absolute Zero. We have limited number of resources available, if these resources are not utilized in optimized manner, the overall productivity and effectiveness will reduce for the entire system.

Therefore we require some alternate methods to make our available resources (Thread / Waiter) more productive and reduce the waiting time that it spends of these time consuming tasks.

Technical Analysis for the same:

Assigning Independent Threads to Each Request is an Expensive Task. In technologies like C# and Java, each request is processed with an independent Thread. The problem with the approach is that Server has Fixed No of Threads in the Thread Pool. Therefore at any moment of time, Maximum Request processed are equal to number of Threads in Thread Pool.

While processing a Request, it may involve expensive I/O Operations, In that case, the Thread remains busy waiting for the time consuming process to be complete. This wastes lot of Thread Processing Time waiting for I/O Operations. Thread might be Idle for maximum time, hence resulting in wastage of Resources and Time.

Working with Node

Node is rather a replacement of such technologies where we have lot of time consuming tasks in the background which can make the thread to wait for a long while. Node focusses on a completely different approach towards solving these kind of problem.

Lets consider the same example of Restaurant who want to work in more optimized manner:

  1. Hotel with the capacity of 50 Tables decides to hire 5 Waiters to Cater to the request. This time we are not assigning a separate waiter to each available table.
  2. Waiter is available to address the customer, while the customer takes time to look for the menu and decide what to order, the waiter is available to address some new customers and cater to some existing customers.
  3. Once the order is decided, the waiter takes the order to the chef for preparation. While the Chef prepares for the food, the waiter is available to cater other customers as well rather than waiting for food to be cooked.
  4. Once the food is prepared, the Waiter brings the food to the customer for Consumption, the customer starts eating the food. Rather than waiting for customer to complete, the chef will move to other customers and cater them simultaneously
  5. Once the customer is done eating, the waiter takes off the cutlery back to Kitchen and process the Bill, the bill is presented to the customer. And this waiter is again available to any other customer.

This way the capacity of Waiter is fully utilized and the resources available to the Hotel are fully utilized. Hence the performance of the system increases.

Node.js Working Structure

Node ensures that these Async Tasks are Event Based and Asynchronous. Creating Event Based architecture ensures that the Main Thread is not waiting for the Asynchronous Request to complete. While the expensive I/O request is processed, Main Thread can switch to another task. This ensures that the Main Thread is always busy. An Event is Fired specifying that the Time Consuming task is executed and further Processing of the Request can be resumed by the Main Thread.

The main concepts that are involved in Node Processing are:

1. Node.js is Single Threaded Event Loop

It is often Mistaken that Node is Multi-Threaded. It is based on Single Threaded Event Loop Architecture. This Event Loop is Single Threaded. All the Requests are received on this Event Thread. Every Requests consists of Asynchronous and Synchronous Execution. The Main Thread is responsible to Execute Only the Synchronous Part of the Request. As soon as Asynchronous I/O Operation is encountered, the Main Thread allocates a Background thread to process the I/O Operation.

Although we have Multiple Threads in the Background, Node is still said to be Single Threaded since all the Requests are Received on the Single Thread and Node internally manages the Execution of Async Process on the Background Threads.

2. Node has Non Blocking I/O Model

Node’s Main Thread does not Wait for External Time Consuming Process to Complete. While the Background Thread is Executing the I/O Function, the Main Thread does not wait for this task to complete. While the Async Task is executed in the Background, the Main Thread is free to take other Requests. Once the Execution of Background Thread is complete, it returns to the Main Thread for Further Execution. Node’s Main Thread is continuously switching between different Requests to execute its Synchronous Part.

3. Event Based, Instead of Waiting for I/O Operation

The Background Thread uses Event Based Approach to Notify Main Thread. Each Async Task consists of some Callback Function associated with it, once the Async Task is Complete, Background Thread raises Event to Notify the Main Thread about the completion of the Async Task. Main Thread might be busy processing some Other Request, Meanwhile the Request waits on the Main Thread, and as soon as Main Thread is free, it takes up the Callback Request for the Further Execution.

--

--

Mayank Gupta
TechnoFunnel

9 Years of Experience with Front-end Technologies and MEAN Stack. Working on all Major UI Frameworks like React, Angular and Vue https://medium.com/technofunnel