1

Scenario: a Nodejs rest API using http.createServer()

Goal: When a SIGNINT comes (in my case from PM2 reload) do a graceful shutdown of the server and then shutdown the DB connection and then exit peacefully.

Code:

// index.js

server.keepAliveTimeout = 10

process.on('SIGINT', () => {
    server.close(err => {
        // close the DB
        ...
        process.exit(0)
    })
})

// the code related to any API response
const headers = {
   ...
   'Connection': 'close'
}
response.writeHead(statusCode, headers)
return response.end(JSON.stringify(data))

Problem: The server.close callback never fires. The PM2 process hits the timeout after (in my case) 20 seconds and so the shutdown is not graceful anymore.

Investigated reason: The callback is fired nicely if NO browser connections are open (e.g. if no one calls the API) or if the API call is made with Firefox. With Chrome instead, I can see in chrome://net-internals/#sockets 1 idle transport_socket_pool after firing a request. In this case the close callback does not fire. As soon as I clear the idle sockets in Chrome the callback fires properly. Note that in Chrome's incognito mode the socket is not kept idle but closed properly, so the callback fires.

Questions:

  • Is it this a bug in Chrome or a normal behavior?
  • Shouldn't the header Connection: close and the short keepAliveTimeout be enough to notify any client that they should not keep any socket open for so long?
  • Which is the proper way to handle clients that prevents server.close to complete?
  • Shall I loop through all the created sockets and close them manually?
stilllife
  • 1,776
  • 1
  • 18
  • 38
  • https://stackoverflow.com/questions/43003870/how-do-i-shut-down-my-express-server-gracefully-when-its-process-is-killed/52602744#52602744 – maxisam Mar 05 '21 at 16:45

0 Answers0