0

I am trying to timeout a response back to the client if its taking too long on my server. But any solution I have found does not seem to trigger the timeout. This should timeout after 2 seconds, but for some reason my endpoint resolves with no timeout happening. Am I doing this correct?

app.use((req, res, next) => {
    res.setTimeout(2000, () => {
        console.log('Request has timed out.');
        res.status(503).send('Service unavailable. Please retry.');
    });
    next();
});

// endpoints
...
// resolves after 5 seconds
app.get('/timeoutTest', (req, res) => {
    const time = new Date().valueOf();
    const futureTime = time + 5000;
    while (new Date().valueOf() < futureTime) {
        // nothing to do but wait
    }
    return res.status(200).send('5 seconds have passed since call');
});

res.setTimout does not seem to be triggering if it has the next() at the bottom of the middleware. However. If I comment out next() it does trigger my res.setTimeout after 2 seconds, but of course any http requests coming in wont get reached because there is no next()

Chipe
  • 4,641
  • 10
  • 36
  • 64
  • 1
    As for the behaviour of next(), it is behaving as it should. node.js is by default single-threaded , however can still behave asynchronously . That means , instructions get scheduled one on top of each other but the thread does not stop executing the instructions that it comes across. So, in your case SetTimeout() gets scheduled to execute after 2000ms but the next() method gets executed first – optimalLight Feb 23 '21 at 00:47
  • @optimalLight so it seems there is no way to back out of an endpoint call, such as in "/timeoutTest" if that endpoint is taking too long? There is no way for something else to be running behind the scenes to resolve the call quicker in the case an endpoint is taking too long? – Chipe Feb 23 '21 at 00:51
  • You can use server.setTimeout(msecs) to set a default timeout on the server. check this answer https://stackoverflow.com/a/52944570/1981231 – optimalLight Feb 23 '21 at 01:03
  • @optimalLight would server.setTimeout kill the server if it timed out, causing the server needing to be started up again? – Chipe Feb 23 '21 at 01:26

1 Answers1

0

There is an express module that will do this already: connect-timeout

Be aware - Node will continue to process your request, so this will not solve CPU usage issues etc.

Alex Taylor
  • 7,128
  • 2
  • 26
  • 22
  • Will the thread still be blocked if another call attempt happens from the client? Will it have to wait till the first one resolves before any new calls come in? – Chipe Feb 23 '21 at 00:49
  • 1
    No, new requests will still be processed. But if there end up being a large number of requests running simultaneously, it could effect system performance. – Alex Taylor Feb 23 '21 at 00:57