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 ?)
Related
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.
I want to know how the engine in node.js know when to call and execute the queued operation. I understand that node.js is single threaded and uses asynchronous non-blocking to execute operations.
But let's say you are calling something from the database and node.js queues the operation and doesn't wait for this to execute further lines of code. Being single thread it stores the data in channels(if I am not wrong). But how does the server know that the network isn't busy and it is the right time to execute the queued operation.
Or it executes the queued operation at the end of the program. This can't be the case. So I am curious to know what happens under the hood and how does the node server know when to execute the queued operation.
It's not clear what you mean by "channels" as that is not a built-in node.js concept or a term that is used internally to describe how node.js works. The tutorial you reference in your comment is talking about the Java language, not the Javascript language so it has absolutely nothing to do with node.js. The concept of "channels" in that tutorial is something that that specific NIO library implements in Java.
But, if you're really just asking how async operations work in node.js, I can explain that generaly concept.
node.js works off an event queue. The node.js interpreter grabs the next event in the event queue and executes it (typically that involves calling a callback function). That callback function runs (single threaded) until it returns. When it returns, the node.js interpreter then looks in the event queue for the next event. If there are any, it grabs that next event and calls the callback associated with it. If there are not events currently in the event queue, then it waits for an event to be put in the event queue (with nothing to do expect perhaps runs some garbage collection).
Now, when you runs some sort of asynchronous operation in your Javascript (such as a DB query), you can your db query function, that initiates the query (by sending the query off to the database) and then immediately returns. This allows your piece of Javascript that started that query to then return and give control back to node.js.
Meanwhile, some native code is managing the connection to your database. When the response comes back from the database, an event is added to the internal node.js event queue.
Whenever the node.js interpreter has finished running other Javascript, it looks in the event queue and pulls out the next event and calls the callback associated with that. In that way, your DB query result gets processed by your code. In all cases here, an asynchronous operation has some sort of callback associated with it that the interpreter can call when it finds the event in the event queue.
Being single thread it stores the data in channels(if I am not wrong).
node.js doesn't have a "channels" concept so I'm not sure what you meant by that.
Or it executes the queued operation at the end of the program.
When the result comes back from the database, some native code managing that will insert an event into the node.js event queue. The Javascript interpreter will service that event, then next time it gets back to the event loop (other Javascript has finished running and it's time to check for the next event to process).
It's important to understand that initiating an asynchronous operation is non-blocking so you get this:
console.log("1");
callSomeAsyncFunction(someData, (err, data) => {
// this callback gets called later when the async operation finishes
// and node.js gets a chance to process the event that was put
// in the event queue by the code that managed the async operation
console.log("2");
});
// right here there is nothing else to do so the interpreter returns back
// to the system, allowing it to process other events
console.log("3");
Because of the non-blocking nature of things, this will log:
1
3
2
Some other references on the topic:
How does JavaScript handle AJAX responses in the background?
Where is the node.js event queue?
Understanding Call backs
Why does a while loop block the node event loop?
Node internally uses the underlying operating systems non-blocking io API-s. See overlapped io, WSAEventSelect for Windows, select for Linux.
I want to know that even though the callbacks are done. How will the callbacks and other process on main thread can be executed parallely if the node is single threaded model.
First off, callbacks are not executed in parallel. There is only ever one thread of Javascript execution at a time so there is no actual parallel execution of Javascript code. You can have multiple asynchronous native code operations in-flight at the same time, but when it comes time for them to run some sort of Javascript completion callback, those are run one at a time, not in parallel.
Javascript is an event driven language which means that things like timers, callbacks from asynchronous disk I/O, callbacks from network operations, etc... use an event queue. When the JS engine finishes executing a piece of Javascript and control is returned back to the system, the JS engine pulls the next event off the event queue and executes it. Native code operations can signal that they are complete and want to run a callback by inserting an event into the event queue.
For an async operation like an HTTP request such as http.get(), here's basically what happens:
Your javascript calls http.get()
That call sends the http request and then returns immediately. Whatever callback you passed to http.get() is stored internally by the http module and is associated with that particular network request.
Your javascript code after the http.get() continues to execute until it is done and returns control back to the system.
Then, some time later, the response from the previous HTTP request comes back to the TCP engine. That causes the http module to insert an event in the Javascript event queue to call your completion callback that you previously sent with http.get().
If the Javascript engine is not doing anything else at the moment, then your callback is executed and passed the result response data.
If the Javascript engine is doing something at the moment, then the event sits in the event queue until the current piece of Javascript that is executing finishes and returns control back to the system. At that point, the JS engine checks the event queue and pulls the next event off the queue and executes it. If that is your callback, then you callback is called at that point.
So, various operations such as async disk I/O, network operations, etc... can run in the background because they are being controlled by native code (not by the Javascript engine). That native code has the ability to use threads if required. The fs module uses threads, the net module does not because the native OS already supports asynchronous networking operations.
Yesterday I was giving some presentation on nodeJS.
Some one asked me following question:
As we know nodeJS is a single threaded server, several request is
coming to the server and it pushes all request to event loop. What if
two request is coming to server at exact same time, how server will
handle this situation?
I guessed a thought and replied back following:
I guess No two http request can come to the server at exact same
time, all request come through a single socket so they will be in queue. Http
request has following format:
timestamp of request is contained in it's header and they may be pushed to the event loop depending upon their timestamp in header.
but I'm not sure whether I gave him right or wrong answer.
I guess No two http request can come to the server at exact same time,
all request come through pipe so they will be in queue.
This part is basically correct. Incoming connections go into the event queue and one of them has to be placed in the queue first.
What if two request is coming two server at exact same time, how
server will handle this situation?
Since the server is listening for incoming TCP connections on a single socket in a single process, there cannot be two incoming connections at exactly the same time. One will be processed by the underlying operating system slightly before the other one. Think of it this way. An incoming connection is a set of packets over a network connection. One of the incoming connections will have its packets before the other one.
Even if you had multiple network cards and multiple network links so two incoming connections could literally arrive at the server at the exact same moment, the node.js queue will be guarded for concurrency by something like a mutex and one of the incoming connections will grab the mutex before the other and get put in the event queue before the other.
The one that is processed by the OS first will be put into the node.js event queue before the other one. When node.js is available to process the next item in the event queue, then whichever incoming request was first in the event queue will start processing first.
Because node.js JS execution is single threaded, the code processing that request will run its synchronous code to completion. If it has an async operation, then it will start that async operation and return. That will then allow the next item in the event queue to be processed and the code for the second request will start running. It will run its synchronous to completion. Like with the first request, if it has an async operation, then it will start that async operation and return.
At that point after both requests have started their async operations and then returned, then its just up to the event queue. When one of those async operations finishes, it will post another event to the event queue and when the single thread of node.js is free, it will again process the next item in the event queue. If both requests have lots of async operations, their progress could interleave and both could be "in-flight" at the same as they fire an async operation and then return until that async operation completes where their processing picks up again when node.js is free to process that next event.
timestamp of request is contained in it's header and they may be
pushed to the event loop depending upon their timestamp in header.
This part is not really right. Incoming events of the same type are added to the queue as they arrive. The first ones to arrive go into the queue first - there's isn't any step that examines some timestamp.
Multiple concurrent HTTP requests are not a problem. Node.js is asynchronous, and will handle multiple requests in the event-loop without having to wait for each one to finish.
For reference, example: https://stackoverflow.com/a/34857298/1157037
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?