Handling slow requests in NodeJs - node.js

For a single request, we can monitor its response time by using consol.log(start) at the beginning of request and console.log(end) at the point where the response is sent.
I want in the event that any request to API hangs for a long period (greater than 5-10s), I should be able to terminate the request, return an error, and log both the request and the stack trace.
How can I be able to do it at the app-level rather than for adding this console.log for each request?
On the server, I do have Nginx.

Related

Is there any workaround to send response until a promise is finished and send another response after it is finished in nodejs express

I have a promise call which takes a long time to return. So I need to send some response like "In progress" until the response is returned. Once it is returned , I need to send another response saying "Done".
I want this in Nodejs-Express App
How to do it?
Using SocketIO would be an option as you would maintain a stream of data open while it is required. But you go beyond of a simple http Express server ...

what happens if neither res.send() nor res.end() is called in express.js?

I have a security issue that someone is trying to call random APIs that are not supported on our server but are frequently used for administrators API in general. and I set this code below to handle 404 to not respond to this attack
url-not-found-handler.js
'use strict';
module.exports = function () {
//4XX - URLs not found
return ((req, res, next) => {
});
};
what happens to client is that it waits until the server responds but I want to know if this will affect the performance of my express.js server also what happens behind the scene in the server without res.send() or res.end() ?
According to the documentation of res.end().
Ends the response process. This method actually comes from Node core,
specifically the response.end() method of http.ServerResponse.
And then response.end
This method signals to the server that all of the response headers and
body have been sent; that server should consider this message
complete. The method, response.end(), MUST be called on each response.
If you leave your request hanging, the httpserver will surely keep data about it. Which means that if you let hang many requests, your memory will grow and reduce your server performance.
About the client, he's going to have to wait until he got a request timeout.
The best to do having a bad request is to immediately reject the request, which is freeing the memory allowed for the request.
You cannot prevent bad requests (maybe have a firewall blocking requests from certains IP address?). Best you can do is to handle them as fast as possible.

Request ending early on ExpressJS

router.route('...')
.get(function(req, res, next) {
// This job() function doing some *long* async task and end of the task calling 3th param as callback
job(param1, param2, function(response) {
// printing response to console perfectly
console.log("callback fired", response);
res.send("response");
});
});
And I'm making my request with curl.
$ curl ... -m 300
curl: (52) Empty reply from server
cURL is waiting for a response for a few minutes and then I'm getting empty reply error. cURL is giving this error before nodejs printing callback fired message.
Same error if I make this request with a browser or with Postman.
I'm sure there are no res.send(), res.end() functions inside job() async function. I stuck, how can I track and found the error?
There are two possible timeouts that could be affecting you. Without seeing the actual network trace (to see what happens when the request ends), I can't tell which timeout might be causing your issue. But, you can just address both of them and it should handle your issue.
First, curl has a timeout value. It is unclear what its default setting is, but you can set whatever value you want with:
curl --max-time 900
where the value is in seconds.
Second, the nodejs http server has a timeout where if no response is sent to an open request, it will close the socket (this keeps dead sockets from building up over time). You can see the doc for server.setTimeout() here. The default for the http server object is 2 minutes (I don't know if Express changes that at all).
The general idea is this:
server.setTimeout(10 * 60 * 1000); // set response timeout to 10 minutes
where the server object would be your http server object (not the Express app object).

why subsequent HTTP requests

My JavaScript makes that ajax call which retrieves a JSON array.
I am trying simulate long running HTTP REST call request that takes longer to return the results.
The way I do it is delay writing anything to the response object on the server side until 5 minutes elapsed since the request landed. After that I set the status to 200 and write the response with the JSON ending the stream.
Putting a breakpoint on the serve side I realize that the request shows up second time but the browser's Network tab does not show another request being made.
It may not be relevant but I am using browsersync middlewars to serve this JSON and write the bytes and end the response in setTimeout().
setTimeout(()=> {
res.statusCode = 200;
res.write(data);
res.end();
});
Question:
Anyone has any explanation as to why this is happening ? And if there is a way to simulate this in another ways ?
In most cases the browser should retry if connection is closed before response. This is a link to the details => HTTP spec Client Behavior if Server Prematurely Closes Connection
BTW it might help you use the chrome throttling options on the network section of dev tools (F12)

Connecting to a Reliable Webservice with Nodejs

My application needs to receive a result from Reliable Webservice. Here is the scenario:-
First I send a CreateSequence request. Then the server replies with a CreateSequenceResponse message. Next I send the actual request to the webservice.
Then the webservice send a response with 202 accept code and sends result in a later message. All these messages contain the header Connection: keep-alive.
I made request with http.ClientRequest. I could capture all responses except the result. http.ClientRequest fires only one response event.
How can I receive the message which contains the result?
Is there any way to listen to socket for remaining data (socket.on('data') did not work). I checked this with ReliableStockQuoteService shipped with Apache Synapse. I appreciate if someone can help me.
When you get the response event, you are given a single argument, which is an http.IncomingMessage, which is a Readable stream. This means that you should bind your application logic on the data event of the response object, not on the request itself.
req.on('response', function (res) {
res.on('data', console.log);
});
Edit: Here is a good article on how to make HTTP requests using Node.

Resources