NodeJs Execute function mutiple times without delay - node.js

i will share the code directly
app.get('/ListBooks', function (req, res) {
console.log("Function called");
//internally calls another URL and sends its response to browser
request({
url: 'someURLinRESTServer',
method: 'POST',
json: MyJsonData
}, function (error, response, body) {
if (error) {
console.log("/Call Failed ->" + error);
res.status(200).send('Failed');
} else {
console.log("/Call got Response");
console.log(response.statusCode, body);
res.send(body); res.end();
}
})
now when the browser generates a request on http://localhost/ListBooks
my node console shows the first message "Function called" and waits for internal REST URL Response
the real problem occurs only when the REST SERVER is down
then if i try to call http://localhost/ListBooks from another browser tab the Node server console doesnt show any changes and only after the repsonse of previous function REST CALL call it displays console message of second function call on app.get('/ListBooks'
i thought node js makes async functions bt here i dnt want functions to wait likes this for multiple instance calls
or is it just a delay in printing message and each function call executes separately .Plz clarify ...

If this is only occurring when the REST server is down (as your comment indicates), then that's just a function of how long your calls to request() take to fail. And, each separate call to request() goes through its own cycle of trying to connect and then eventually timing out. If both are timing out, then you will issue request1, then request2, then some timeout amount of time will pass and request1 will fail and then request2 will fail shortly after it. This has nothing to do with how express handles multiple requests and everything to do with how the calls to your REST server behave.
You can set the timeout option for request() if you want to shorten how long it will wait for a response, but you do need to make sure you don't shorten it so much that a busy REST server that just takes a little while to actually respond gets timed out.
or is it just a delay in printing message and each function call
executes separately
Each call is acting completely separately. There is no serialization of these responses by node.js or by Express. The appearance of serialization is just because they both take the same amount of time to fail with a timeout so they will fail one after the other.

Related

With Node.js, Express when the end of a route is hit does all asynchronous code that has not yet completed stop?

Environment: Node.js, Express
Question: When the end of a route is hit does all asynchronous code that has not yet completed stop? I have been experimenting for several hours and this seems to be true but is there a definitive answer?
Example: In the simplified example below when the / route is hit getInfoAndSaveIt is called. This function has a fetch call that will be slow followed by a database save that will also be slow. In the route the program will certainly reach the line res.render('homepage'); before the function has completed. In this case does homepage render and all async code in the function that has not yet completed stop? Or alternately does the async code continue in the background even though the end of the route has been hit?
app.get('/', function(req, res) {
getInfoAndSaveIt();
res.render('homepage');
});
function getInfoAndSaveIt() {
let randomData = fetch('https://www.example.com/data.txt');
User.updateOne({ data: randomData }, { id: 'abc123' });
}
With Node.js, Express when the end of a route is hit does all asynchronous code that has not yet completed stop?
No. Asynchronous code has a mind of its own and has no direct connection to a particular route. For example, imagine you were using some asynchronous code to do some logging. You send the response and then you call some asynchronous code to log some data. That logging will continue on just fine. It has no direct connection to the route. It's just Javascript running in the interpreter.
As for your example:
In this case does homepage render and all async code in the function that has not yet completed stop?
Yes, the homepage will render. Your async code will finish on its own.
Or alternately does the async code continue in the background even though the end of the route has been hit?
Yes, the async code continues on its own.
Try this simple example:
app.get('/', function(req, res) {
setTimeout(() => {
console.log("timer fired");
}, 2000);
res.render('homepage');
console.log("done rendering page");
});
When you hit this route, you will see this in the server logs:
done rendering page
timer fired
As evidence that an asynchronous operation continues after the route is done.
Keep in mind that processing a route in node.js is just another asynchronous operation. It's not some magic process thing or thread thing. It's just an asynchronous operation triggered by the incoming http request. So, there's no magic properties that would go find all asynchronous operations started by this and kill them somehow. That's not how node.js works. It's the opposite. Once you start them, they have a mind of their own and will complete regardless of what else is doing on in the process unless the process crashes or you specifically call process.exit().

How long does it take for Ajax success function to wait a response from the server?

When making Ajax call to an API which fetches data from db and returns response back to the callback function of the Ajax call made.
How much time does it take for this callback function to wait for a response
from the API which fetches data from db ?
Is there a way of increasing this time of waiting for a response by the
callback function of the Ajax call made?
Yes, you can customise the timeout for the request.
Assuming, you are using jQuery. If not, you can customise timeout for raw XHR request as well, just google out the syntax
Below is an example, of how to do it:
$.ajax({
url: "/url/to/the/endpoint",
error: function(){
// will fire when timeout is reached, or server responded with error status code
},
success: function(){
//will fire when 200 success was received from the server
},
timeout: 3000 // sets timeout to 3000 milliseconds, You can change according to your need
});
Hope it helps!

Request module: what if server doesn't respond?

The Node JS request module has a callback containing that fires whenever the response is received, but what if the server doesn't respond?
I will illustrate it with an example.
My code looks like this:
request(TARGET_URL, function (error, response, body) {
if (response.statusCode == 200) doSomething()
})
So, again: what if the server doesn't respond? How can I avoid the program execution to halt if the TARGET_URL server doesn't respond?
In this case a callback function still will be called after some time, but its first argument won't be empty. Quoting the doc:
There are two main types of timeouts: connection timeouts and read
timeouts. A connect timeout occurs if the timeout is hit while your
client is attempting to establish a connection to a remote machine
(corresponding to the connect() call on the socket). A read timeout
occurs any time the server is too slow to send back a part of the
response.
These two situations have widely different implications for what went
wrong with the request, so it's useful to be able to distinguish them.
You can detect timeout errors by checking err.code for an 'ETIMEDOUT'
value. Further, you can detect whether the timeout was a connection
timeout by checking if the err.connect property is set to true.
request.get('http://10.255.255.1', {timeout: 1500}, function(err) {
console.log(err.code === 'ETIMEDOUT');
// Set to `true` if the timeout was a connection timeout, `false` or
// `undefined` otherwise.
console.log(err.connect === true);
process.exit(0);
});
Note that { timeout : 1500 } part: with this approach you can set a specific time for a specific request to be processed.

Catching Mocha timeouts

I'm writing a node.js web service which needs to communicate with another server. So its basically server to server communication. I don't have any previous experience of writing web services so I have very limited knowledge. For unit tests I'm using Mocha.
Now, I intend to test the behavior of my service for a particular scenario when this other server doesn't respond to my GET request and the request is actually timed out. For tests I've created a fake client and server around my web service. My web service now takes request from this fake client and then gets information from another fake server that I created which then returns the response in the expected format. To simulate timeout I don't do response.end() from my route handler. The problem is that Mocha judges it to have failed this test case.
Is there a way I could catch this intentional timeout in Mocha and the test is a success?
As mido22 suggested you should use handle the timeout generated by whatever library you use to connect. For instance, with request:
var request = require("request");
it("test", function (done) {
request("http://www.google.com:81", {
timeout: 1000
}, function (error, response, body) {
if (error && error.code === 'ETIMEDOUT') {
done(); // Got a timetout: that's what we wanted.
return;
}
// Got another error or no error at all: that's bad!
done(error || new Error("did not get a timeout"));
});
});

node.js wait for response

I have a very limited knowledge about node and nob-blocking IO so forgive me if my question is too naive.
In order to return needed information in response body, I need to
Make a call to 3rd party API
Wait for response
Add some modifications and return JSON response with the information I got from API.
My question is.. how can I wait for response? Or is it possible to send the information to the client only when I received response from API (as far as I know, connection should be bidirectional in this case which means I won't be able to do so using HTTP).
And yet another question. If one request waits for response from API, does this mean than other users will be forced to wait too (since node is single-threaded) until I increase numbers of threads/processes from 1 to N?
You pass a callback to the function which calls the service. If the service is a database, for example:
db.connect(host, callback);
And somewhere else in the code:
var callback = function(err, dbObject) {
// The connection was made, it's safe to handle the code here
console.log(dbObject.status);
res.json(jsonObject, 200)
};
Or you can use anonymous functions, so:
db.connect(host, function(err, dbObject) {
// The connection was made, it's safe to handle the code here
console.log(dbObject.status);
res.json(jsonObject, 200)
});
Between the call and the callback, node handles other clients / connections freely, "non-blocking".
This type of situation is exactly what node was designed to solve. Once you receive the request from your client, you can make a http request, which should take a callback parameter. This will call your callback function when the request is done, but node can do other work (including serving other clients) while you are waiting for the response. Once the request is done, you can have your code return the response to the client that is still waiting.
The amount of memory and CPU used by the node process will increase as additional clients connect to it, but only one process is needed to handle many simultaneous clients.
Node focuses on doing slow I/O asynchronously, so that the application code can start a task, and then have code start executing again after the I/O has completed.
An typical example might make it clear. We make a call to the FB API. When we get a response, we modify it and then send JSON to the user.
var express = require('express');
var fb = require('facebook-js');
app.get('/user', function(req, res){
fb.apiCall('GET', '/me/', {access_token: access_token}, function(error, response, body){ // access FB API
// when FB responds this part of the code will execute
if (error){
throw new Error('Error getting user information');
}
body.platform = 'Facebook' // modify the Facebook response, available as JSON in body
res.json(body); // send the response to client
});
});

Resources