Nodejs callback mechanism - which thread handles the callback? - node.js

I'm new to nodeJS and was wondering about the single-instance model of Node.
In a simple nodeJs application, when some blocking operation is asynchronously handled with callbacks, does the main thread running the nodeJs handle the callback as well?.
If the request is to get some data off the database, and there are 100s of concurrent users, and each db operation takes couple of seconds, when the callback is finally fired (for each of the connections), is the main thread accepting these requests used for executing the callback as well? If so, how does nodeJs scale and how does it respond so fast?.

Each instance of nodejs runs in a single thread. Period. When you make an async call to, say, a network request, it doesn't wait around for it, not in your code or anywhere else. It has an event loop that runs through. When the response is ready, it invokes your callback.
This can be incredibly performant, because it doesn't need lots of threads and all the memory overhead, but it means you need to be careful not to do synchronous blocking stuff.
There is a pretty decent explanation of the event loop at http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ and the original jsconf presentation by Ryan Dahl http://www.youtube.com/watch?v=ztspvPYybIY is worth watching. Ever seen an engineer get a standing ovation for a technical presentation?

Related

Node JS multiple request handling

NodeJs is single-threaded means it has one main thread that cares about our operations and for the rest of asynchronous, it gives the task to another thread.
So as per understanding callback results in offloading the current task to a separate thread.
app.post("/get",(req,res)=>{
res.status(200).json({message:"Success"})
})
Does the above statement execute in another thread?
Everything in a Javascript program runs in one thread (unless you use workers, which your example does not).
Javascript runs with a main loop. The main loop reads a queue of events and processes them one by one. All sorts of things turn into events in that queue: incoming web requests, timeouts, intervals, promises awaiting resolution, messages, you name it. It's more complex than this, of course.
It's good that it's all one thread: you don't have to worry about thread concurrency.
There's a downside: if you write a long-running method, its execution will block the main loop until it's finished. This makes web pages janky and nodejs programs have slow response. Use workers (separate threads) for that stuff.
The method in a .post() like yours is run in response to an event on the queue announcing an incoming web request.
Read about the main loop.

How, in general, does Node.js handle 10,000 concurrent requests?

I understand that Node.js uses a single-thread and an event loop to process requests only processing one at a time (which is non-blocking). But still, how does that work, lets say 10,000 concurrent requests. The event loop will process all the requests? Would not that take too long?
I can not understand (yet) how it can be faster than a multi-threaded web server. I understand that multi-threaded web server will be more expensive in resources (memory, CPU), but would not it still be faster? I am probably wrong; please explain how this single-thread is faster in lots of requests, and what it typically does (in high level) when servicing lots of requests like 10,000.
And also, will that single-thread scale well with that large amount? Please bear in mind that I am just starting to learn Node.js.
If you have to ask this question then you're probably unfamiliar with what most web applications/services do. You're probably thinking that all software do this:
user do an action
│
v
application start processing action
└──> loop ...
└──> busy processing
end loop
└──> send result to user
However, this is not how web applications, or indeed any application with a database as the back-end, work. Web apps do this:
user do an action
│
v
application start processing action
└──> make database request
└──> do nothing until request completes
request complete
└──> send result to user
In this scenario, the software spend most of its running time using 0% CPU time waiting for the database to return.
Multithreaded network app:
Multithreaded network apps handle the above workload like this:
request ──> spawn thread
└──> wait for database request
└──> answer request
request ──> spawn thread
└──> wait for database request
└──> answer request
request ──> spawn thread
└──> wait for database request
└──> answer request
So the thread spend most of their time using 0% CPU waiting for the database to return data. While doing so they have had to allocate the memory required for a thread which includes a completely separate program stack for each thread etc. Also, they would have to start a thread which while is not as expensive as starting a full process is still not exactly cheap.
Singlethreaded event loop
Since we spend most of our time using 0% CPU, why not run some code when we're not using CPU? That way, each request will still get the same amount of CPU time as multithreaded applications but we don't need to start a thread. So we do this:
request ──> make database request
request ──> make database request
request ──> make database request
database request complete ──> send response
database request complete ──> send response
database request complete ──> send response
In practice both approaches return data with roughly the same latency since it's the database response time that dominates the processing.
The main advantage here is that we don't need to spawn a new thread so we don't need to do lots and lots of malloc which would slow us down.
Magic, invisible threading
The seemingly mysterious thing is how both the approaches above manage to run workload in "parallel"? The answer is that the database is threaded. So our single-threaded app is actually leveraging the multi-threaded behaviour of another process: the database.
Where singlethreaded approach fails
A singlethreaded app fails big if you need to do lots of CPU calculations before returning the data. Now, I don't mean a for loop processing the database result. That's still mostly O(n). What I mean is things like doing Fourier transform (mp3 encoding for example), ray tracing (3D rendering) etc.
Another pitfall of singlethreaded apps is that it will only utilise a single CPU core. So if you have a quad-core server (not uncommon nowdays) you're not using the other 3 cores.
Where multithreaded approach fails
A multithreaded app fails big if you need to allocate lots of RAM per thread. First, the RAM usage itself means you can't handle as many requests as a singlethreaded app. Worse, malloc is slow. Allocating lots and lots of objects (which is common for modern web frameworks) means we can potentially end up being slower than singlethreaded apps. This is where node.js usually win.
One use-case that end up making multithreaded worse is when you need to run another scripting language in your thread. First you usually need to malloc the entire runtime for that language, then you need to malloc the variables used by your script.
So if you're writing network apps in C or go or java then the overhead of threading will usually not be too bad. If you're writing a C web server to serve PHP or Ruby then it's very easy to write a faster server in javascript or Ruby or Python.
Hybrid approach
Some web servers use a hybrid approach. Nginx and Apache2 for example implement their network processing code as a thread pool of event loops. Each thread runs an event loop simultaneously processing requests single-threaded but requests are load-balanced among multiple threads.
Some single-threaded architectures also use a hybrid approach. Instead of launching multiple threads from a single process you can launch multiple applications - for example, 4 node.js servers on a quad-core machine. Then you use a load balancer to spread the workload amongst the processes. The cluster module in node.js does exactly this.
In effect the two approaches are technically identical mirror-images of each other.
What you seem to be thinking is that most of the processing is handled in the node event loop. Node actually farms off the I/O work to threads. I/O operations typically take orders of magnitude longer than CPU operations so why have the CPU wait for that? Besides, the OS can handle I/O tasks very well already. In fact, because Node does not wait around it achieves much higher CPU utilisation.
By way of analogy, think of NodeJS as a waiter taking the customer orders while the I/O chefs prepare them in the kitchen. Other systems have multiple chefs, who take a customers order, prepare the meal, clear the table and only then attend to the next customer.
Single Threaded Event Loop Model Processing Steps:
Clients Send request to Web Server.
Node JS Web Server internally maintains a Limited Thread pool to
provide services to the Client Requests.
Node JS Web Server receives those requests and places them into a
Queue. It is known as “Event Queue”.
Node JS Web Server internally has a Component, known as “Event Loop”.
Why it got this name is that it uses indefinite loop to receive
requests and process them.
Event Loop uses Single Thread only. It is main heart of Node JS
Platform Processing Model.
Event Loop checks any Client Request is placed in Event Queue. If
not then wait for incoming requests for indefinitely.
If yes, then pick up one Client Request from Event Queue
Starts process that Client Request
If that Client Request Does Not requires any Blocking IO
Operations, then process everything, prepare response and send it
back to client.
If that Client Request requires some Blocking IO Operations like
interacting with Database, File System, External Services then it
will follow different approach
Checks Threads availability from Internal Thread Pool
Picks up one Thread and assign this Client Request to that thread.
That Thread is responsible for taking that request, process it,
perform Blocking IO operations, prepare response and send it back
to the Event Loop
very nicely explained by #Rambabu Posa for more explanation go throw this Link
I understand that Node.js uses a single-thread and an event loop to
process requests only processing one at a time (which is non-blocking).
I could be misunderstanding what you've said here, but "one at a time" sounds like you may not be fully understanding the event-based architecture.
In a "conventional" (non event-driven) application architecture, the process spends a lot of time sitting around waiting for something to happen. In an event-based architecture such as Node.js the process doesn't just wait, it can get on with other work.
For example: you get a connection from a client, you accept it, you read the request headers (in the case of http), then you start to act on the request. You might read the request body, you will generally end up sending some data back to the client (this is a deliberate simplification of the procedure, just to demonstrate the point).
At each of these stages, most of the time is spent waiting for some data to arrive from the other end - the actual time spent processing in the main JS thread is usually fairly minimal.
When the state of an I/O object (such as a network connection) changes such that it needs processing (e.g. data is received on a socket, a socket becomes writable, etc) the main Node.js JS thread is woken with a list of items needing to be processed.
It finds the relevant data structure and emits some event on that structure which causes callbacks to be run, which process the incoming data, or write more data to a socket, etc. Once all of the I/O objects in need of processing have been processed, the main Node.js JS thread will wait again until it's told that more data is available (or some other operation has completed or timed out).
The next time that it is woken, it could well be due to a different I/O object needing to be processed - for example a different network connection. Each time, the relevant callbacks are run and then it goes back to sleep waiting for something else to happen.
The important point is that the processing of different requests is interleaved, it doesn't process one request from start to end and then move onto the next.
To my mind, the main advantage of this is that a slow request (e.g. you're trying to send 1MB of response data to a mobile phone device over a 2G data connection, or you're doing a really slow database query) won't block faster ones.
In a conventional multi-threaded web server, you will typically have a thread for each request being handled, and it will process ONLY that request until it's finished. What happens if you have a lot of slow requests? You end up with a lot of your threads hanging around processing these requests, and other requests (which might be very simple requests that could be handled very quickly) get queued behind them.
There are plenty of others event-based systems apart from Node.js, and they tend to have similar advantages and disadvantages compared with the conventional model.
I wouldn't claim that event-based systems are faster in every situation or with every workload - they tend to work well for I/O-bound workloads, not so well for CPU-bound ones.
Adding to slebetman answer:
When you say Node.JS can handle 10,000 concurrent requests they are essentially non-blocking requests i.e. these requests are majorly pertaining to database query.
Internally, event loop of Node.JS is handling a thread pool, where each thread handles a non-blocking request and event loop continues to listen to more request after delegating work to one of the thread of the thread pool. When one of the thread completes the work, it send a signal to the event loop that it has finished aka callback. Event loop then process this callback and send the response back.
As you are new to NodeJS, do read more about nextTick to understand how event loop works internally.
Read blogs on http://javascriptissexy.com, they were really helpful for me when I started with JavaScript/NodeJS.
The blocking part of the multithreaded-blocking system makes it less efficient. The thread which is blocked cannot be used for anything else, while it is waiting for a response.
While a non-blocking single-threaded system makes the best use of its single-thread system.
See diagram below:
Here waiting at kitchen door or waiting while customer is selecting food items, is "Blocking" the full capacity of the waiter. In sense of Compute systems, it could be waiting for IO, or DB response or anything which blocks whole thread, even though the thread is capable of other works while waiting.
Let see how non blocking works:
In a non blocking system, waiter only takes order and serve order, do not waits at anywhere. He shares his mobile number, to give a call back when they have finalzed the order. Similarly he shares his number with Kitchen to callback when order is ready to serve.
This is how Event loop works in NodeJS, and performs better than blocking multithreaded system.
Adding to slebetman's answer for more clarity on what happens while executing the code.
The internal thread pool in nodeJs just has 4 threads by default. and its not like the whole request is attached to a new thread from the thread pool the whole execution of request happens just like any normal request (without any blocking task) , just that whenever a request has any long running or a heavy operation like db call ,a file operation or a http request the task is queued to the internal thread pool which is provided by libuv. And as nodeJs provides 4 threads in internal thread pool by default every 5th or next concurrent request waits until a thread is free and once these operations are over the callback is pushed to the callback queue. and is picked up by event loop and sends back the response.
Now here comes another information that its not once single callback queue, there are many queues.
NextTick queue
Micro task queue
Timers Queue
IO callback queue (Requests, File ops, db ops)
IO Poll queue
Check Phase queue or SetImmediate
close handlers queue
Whenever a request comes the code gets executing in this order of callbacks queued.
It is not like when there is a blocking request it is attached to a new thread. There are only 4 threads by default. So there is another queueing happening there.
Whenever in a code a blocking process like file read occurs , then calls a function which utilises thread from thread pool and then once the operation is done , the callback is passed to the respective queue and then executed in the order.
Everything gets queued based on the the type of callback and processed in the order mentioned above.
Here is a good explanation from this medium article:
Given a NodeJS application, since Node is single threaded, say if processing involves a Promise.all that takes 8 seconds, does this mean that the client request that comes after this request would need to wait for eight seconds?
No. NodeJS event loop is single threaded. The entire server architecture for NodeJS is not single threaded.
Before getting into the Node server architecture, to take a look at typical multithreaded request response model, the web server would have multiple threads and when concurrent requests get to the webserver, the webserver picks threadOne from the threadPool and threadOne processes requestOne and responds to clientOne and when the second request comes in, the web server picks up the second thread from the threadPool and picks up requestTwo and processes it and responds to clientTwo. threadOne is responsible for all kinds of operations that requestOne demanded including doing any blocking IO operations.
The fact that the thread needs to wait for blocking IO operations is what makes it inefficient. With this kind of a model, the webserver is only able to serve as much requests as there are threads in the thread pool.
NodeJS Web Server maintains a limited Thread Pool to provide services to client requests. Multiple clients make multiple requests to the NodeJS server. NodeJS receives these requests and places them into the EventQueue .
NodeJS server has an internal component referred to as the EventLoop which is an infinite loop that receives requests and processes them. This EventLoop is single threaded. In other words, EventLoop is the listener for the EventQueue.
So, we have an event queue where the requests are being placed and we have an event loop listening to these requests in the event queue. What happens next?
The listener(the event loop) processes the request and if it is able to process the request without needing any blocking IO operations, then the event loop would itself process the request and sends the response back to the client by itself.
If the current request uses blocking IO operations, the event loop sees whether there are threads available in the thread pool, picks up one thread from the thread pool and assigns the particular request to the picked thread. That thread does the blocking IO operations and sends the response back to the event loop and once the response gets to the event loop, the event loop sends the response back to the client.
How is NodeJS better than traditional multithreaded request response model?
With traditional multithreaded request/response model, every client gets a different thread where as with NodeJS, the simpler request are all handled directly by the EventLoop. This is an optimization of thread pool resources and there is no overhead of creating the threads for every client request.
In node.js request should be IO bound not CPU bound. It means that each request should not force node.js to do a lot of computations. If there are a lot of computations involved in solving a request then node.js is not a good choice. IO bound has little computation required. most of the time requests are spent in either making a call to a DB or a service.
Node.js has single-threaded event loop but it is just a chef. Behind the scene most of the work is done by the operating system and Libuv ensures the communication from the OS. From the Libuv docs:
In event-driven programming, an application expresses interest in
certain events and respond to them when they occur. The responsibility
of gathering events from the operating system or monitoring other
sources of events is handled by libuv, and the user can register
callbacks to be invoked when an event occurs.
The incoming requests are handled by the Operating system. This is pretty much correct for almost all servers based on request-response model. Incoming network calls are queued in OS Non-blocking IO queue.'Event Loop constantly polls OS IO queue that is how it gets to know about the incoming client request. "Polling" means checking the status of some resource at a regular interval. If there are any incoming requests, evnet loop will take that request, it will execute that synchronously. while executing if there is any async call (i.e setTimeout), it will be put into the callback queue. After the event loop finishes executing sync calls, it can poll the callbacks, if it finds a callback that needs to be executed, it will execute that callback. then it will poll for any incoming request. If you check the node.js docs there is this image:
From docs phase-overview
poll: retrieve new I/O events; execute I/O related callbacks (almost
all with the exception of close callbacks, the ones scheduled by
timers, and setImmediate()); node will block here when appropriate.
So event loop is constantly polling from different queues. If ant request needs to an external call or disk access, this is passed to OS and OS also has 2 different queues for those. As soon as event loop detects that somehting has to be done async, it puts them in a queue. Once it is put in a queue, event-loop will process to the next task.
One thing that to mention here, event loop continuously runs. Only Cpu can move this thread out of CPU, event loop itself will not do it.
From the docs:
The secret to the scalability of Node.js is that it uses a small
number of threads to handle many clients. If Node.js can make do with
fewer threads, then it can spend more of your system's time and memory
working on clients rather than on paying space and time overheads for
threads (memory, context-switching). But because Node.js has only a
few threads, you must structure your application to use them wisely.
Here's a good rule of thumb for keeping your Node.js server speedy:
Node.js is fast when the work associated with each client at any given
time is "small".
Note that small tasks mean IO bound tasks not CPU. Single event loop will handle the client load only if the work for each request is mostly IO work.
Context switch basically means CPU is out of resources so It needs to stop the execution of one process to allow another process to execute. OS first has to evict process1 so it will take this process from CPU and it will save this process in the main memory. Next, OS will restore process2 by loading process control block from memory and it will put it on the CPU for execution. Then process2 will start its execution. Between process1 ended and the process2 started, we have lost some time. Large number of threads can cause a heavily loaded system to spend precious cycles on thread scheduling
and context switching, which adds latency and imposes limits on scalability and throughput.

Node.js + express.js and thread safety

Assume I have an array of items and each GET call make a change on this array (may be add/remove/shift)
Would that be "thread-safe"? I know that Node.js is a single-threaded, yet is there a possibility that two GET requests would be handled "simultaneously"?
As node is single-threaded only one piece of code is ever being executed at any time. A callback (such as the callback from a remote HTTP GET request) will be added to the end of the event loop's message queue. When there are no more functions on the stack, the program waits for a message to be added to the queue, and runs the message's function (in this case, the request callback function).
If you are making parallel requests to a remote server then you won't get the requests completed in the same order each time unless you run the requests in series. The callback functions will never run at the same time, however - only one function can ever be executed at once.
It would be thread safe because all operation on arrays are blocking. The only operations in node.js that are not blocking are I/Os.
Since you don't have any async operation, there is no problem with your situation. (Except if you need to do something like an access to a database or such ?)

nodejs - Why Node.js can handle large number of simulteneous persistent connections?

I know Node.js is good at keeping large number of simultaneous persistent connections, for example, a chat room for many many chatters.
I am wondering how it achieves this. I mean anyway it is using TCP/IP which is encapsulated by the underlying OS, why it can handle persistent connections so well that others cannot?
What is the magic thing does it have?
Node.js makes all I/O asynchronous. It only runs in a single thread, but will do other requests or operations while waiting on I/O.
In contrast, classical web servers will not serve another request until the previous one is fully done. For this reason, Apache runs several processes at the same time; let's say there's 10 httpd processes, that normally means 10 requests can be served at any one time (*). If the processes take more time to complete, you will serve less requests - or will have to spawn more processes, even if the process is doing nothing - like waiting for the database to chew up and return data.
A node.js process, faced with a request that will go to the database, leaves the database to work while it goes to serve another request.
*) MPM makes this not quite true, but true enough for all intents and purposes.
Well, the thing is that most web servers (like apache etc.. ) works using thread spawning, where they spwan a new thread for every incoming HTTP request. these threads are synchronous and blocking in nature => which means they will execute the code in the order it is written and any further computation will be blocked by the current I/O or compute task. Like if you want to listen for an event like - chat submission by a chatter you need to have a dedicated thread per user ( per user is necessary for maintaining persistent connection, there are few possible optimization techniques but still you can assume threads to be per user) listening to this event and this thread will be blocked waiting for this event to happen. So for any thread spawning and blocking web-server
Javascript on the other hand is non-blocking ( and conductive to asynchronous codes )by nature => here you register a callback for an event and whenever it occurs some the callback function will be executed. It will not block at any point waiting for this event.
You can find more about this by reading about non-blocking or asynchronous servers.

How node.js works?

I don't understand several things about nodejs. Every information source says that node.js is more scalable than standard threaded web servers due to the lack of threads locking and context switching, but I wonder, if node.js doesn't use threads how does it handle concurrent requests in parallel? What does event I/O model means?
Your help is much appreciated.
Thanks
Node is completely event-driven. Basically the server consists of one thread processing one event after another.
A new request coming in is one kind of event. The server starts processing it and when there is a blocking IO operation, it does not wait until it completes and instead registers a callback function. The server then immediately starts to process another event (maybe another request). When the IO operation is finished, that is another kind of event, and the server will process it (i.e. continue working on the request) by executing the callback as soon as it has time.
So the server never needs to create additional threads or switch between threads, which means it has very little overhead. If you want to make full use of multiple hardware cores, you just start multiple instances of node.js
Update
At the lowest level (C++ code, not Javascript), there actually are multiple threads in node.js: there is a pool of IO workers whose job it is to receive the IO interrupts and put the corresponding events into the queue to be processed by the main thread. This prevents the main thread from being interrupted.
Although Question is already explained before a long time, I'm putting my thoughts on the same.
Node.js is single threaded JavaScript runtime environment. Basically it's creator Ryan Dahl concern was that parallel processing using multiple threads is not the right way or too complicated.
if Node.js doesn't use threads how does it handle concurrent requests in parallel
Ans: It's completely wrong sentence when you say it doesn't use threads, Node.js use threads but in a smart way. It uses single thread to serve all the HTTP requests & multiple threads in thread pool(in libuv) for handling any blocking operation
Libuv: A library to handle asynchronous I/O.
What does event I/O model means?
Ans: The right term is non-blocking I/O. It almost never blocks as Node.js official site says. When any request goes to node server it never queues the request. It take request and start executing if it's blocking operation then it's been sent to working threads area and registered a callback for the same as soon as code execution get finished, it trigger the same callback and goes to event queue and processed by event loop again after that create response and send to the respective client.
Useful link:
click here
Node JS is a JavaScript runtime environment. Both browser and Node JS run on V8 JavaScript engine. Node JS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node JS applications uses single threaded event loop architecture to handle concurrent clients. Actually its' main event loop is single threaded but most of the I/O works on separate threads, because the I/O APIs in Node JS are asynchronous/non-blocking by design, in order to accommodate the main event loop. Consider a scenario where we request a backend database for the details of user1 and user2 and then print them on the screen/console. The response to this request takes time, but both of the user data requests can be carried out independently and at the same time. When 100 people connect at once, rather than having different threads, Node will loop over those connections and fire off any events your code should know about. If a connection is new it will tell you .If a connection has sent you data, it will tell you .If the connection isn’t doing anything ,it will skip over it rather than taking up precision CPU time on it. Everything in Node is based on responding to these events. So we can see the result, the CPU stay focused on that one process and doesn’t have a bunch of threads for attention.There is no buffering in Node.JS application it simply output the data in chunks.
Though its been answered , i would like to just share my understandings in simple terms
Nodejs uses a library called Libuv , so this Libuv is written in C
language which uses the concept of threads . These threads are called
as workers and these workers take care of the multiple requests from client.
Parallel processing in nodejs is achieved with the help of 2 concepts
Asynchronous
Non blocking IO

Resources