Implementing Node.js Architecture in Python

Node.js is great. It is said to solve the legacy 10K concurrency issue. The architecture that sits behind this massive beauty is something I will try to explain. Once you have the hold of it, I will tell you how you could reach a similar architecture to massively scale your traffic handling if your main stack is Python.

Understanding Nodejs Architecture in detail:
Node.js is a single-threaded, runtime environment for Javascript to run at the server. Well, if you are a complete beginner, you might have lost me in the first line itself, but let me explain to you each with an analogy.

Single-Threaded Analogy - Let's suppose, you are sitting in a restaurant. The restaurant has a single waiter. The waiter comes in, takes your order, and delegates the order to the kitchen. Here the waiter is considered as single-threaded. As there is only one to take your orders. In the same way, Nodejs provides you with only a single thread to take every request.

Runtime Environment Analogy - For all the beginners, never call Node.js a programming language, it is a runtime. Runtime environments are something that is shipped with all the tools in order to run a program. For example, Java has its runtime as JRE. Javascript support is not given to servers out of the box, but it is packed within an environment called Nodejs.

Let's stretch our analogy of restaurant to understand the internals and beauty of Nodejs in more detail Suppose there are 10 tables that are occupied inside a restaurant waiting for the orders and there is only one waiter. Let's think of multiple scenarios in which the orders from each table will be processed.

Scenario 1:
The waiter goes to the first table, takes the order, goes inside the kitchen, delegates the order to the kitchen, and hangs around while the order is completed and then moves to the next table. You see if a particular takes around 12 minutes to complete and there are 10 tables, the total time taken would be 10X12 = 120 minutes. Maths is simple, you might lose all the customers, and your resources are unutilized too. Total loss.

Scenario 2:
The waiter goes to the first table, takes the order, and delegates it to the kitchen, and one by one, he takes all the orders. Meanwhile, if an order is completed, he brings the dish back to the table. You see if 10 tables are served simultaneously and making dishes takes 12 minutes, the total time taken would be 12 minutes. The best part is your every resource from the kitchen to the waiter is utilized to its best of capacity. Total Profit.

Let's take this analogy and understand this from my diagram

So now when I say, Nodejs is single-threaded, runtime for javascript on the server which asynchronously listens internally to any requests sitting inside the event queue, and then once the task is complete, it calls a callback function and the request is complete, you kinda get me.
Nodejs is blazingly fast and it is well known for CPU resource utilization. It is also said to solve the C10K problem and now you know why.

A brief talk about Asynchronousity
If you are a complete beginner and never coded before, you might have seen that any scripting language reads the code line by line. At least, that is how it was developed at its inception. A good example of synchronous code looks like this:

The code you see above is some gibberish code, however, you might have got a basic idea with what the code is doing. But there is a problem with this approach. The problem is the same, the "scenario 1" issue. The first line is blocking I/O operation and take some time to be executed. So our code sits there allocating all the resources and wait. Our code is literally doing nothing in the time when the read operation is going on or other such operations. We could have done other CPU operations or could have completed other small tasks in the meantime while the first line is still waiting to be executed.

How this thing works in Asynchronous fashion

You might be confused by seeing the async/await but these two are really powerful things. First of all, this is an asynchronous code block. It means that when some blocking operations occur, CPU is free to use its resources for other tasks in OS. when the task is complete it will return the output to file which then can be processed further. Believe it or not, you might see a huge spike in your code performance if you start using it correctly.
Javascript uses this thing by default but we have to integrate it manually to other programming languages.

So, in brief, the Nodejs looks something like this

You might have guessed well the architecture on your own just by following the analogy.

Let's Python
Python is easy but python is slow. Why? Because earlier it followed the "Scenario 1" condition. The recent (not so recent) versions in Python introduced a new library called asyncio. The asyncio lets developers make their code to behave asynchronously.
There are lots of frameworks out there in python which when combined with asyncio makes your runtime behave as node.js. One such is aiohttp.
The aiohttp framework is a client/server package that supports the asyncio package.
Let's understand how it works in Python. In synchronous aka Scenario 1, the code looks like this:

The code block calls the hello function which includes a code line that sends an HTTP get-request to an API and once the response is returned it prints the output. The problem with this is the same. Until and unless the output is returned, it hangs there and waits.

Let's write this in aiohttp

Before understanding the code, one thing to note down is that you won't see any performance spike for a single request. Think about calling hello for 10,000 times. It is found that running the synchronous one took 2:45:54 hours. Whereas the asynchronous code took 00:03:48 minutes.

In the code block, you might see a line, where we fetch the event loop. The event loop keeps track of all the processes.
The code is self-explanatory. The event loop continuously watches for the output. In the mean-time CPU is free to do other tasks.

Written By
Anurag Tiwari
Data Scientist

Ask For Demo?Call our 24/7 Sales & Support at (480) 624 2500