8

I'm creating an Express server with reloadable endpoints.
To make this possible I created an endpoint for such a purpose.

But when I call server.close() on the Express's HTTP server it still continues listening, while the server.listening says otherwise, it still is.

Here is a simplified version of my script (Not working fully, but you get the gist):

class simpleServer {
    constructor() {
         let express = require('express');
         this.app = express();
         this.app.get('/reload', this.reload);
         this.server = this.app.listen(3000);
    }

    reload(req, res) {
         console.log('Closing server');             

         this.server.close(function() {
             console.log('Closed server');
         });
         
         // Re-init & stuff

         res.json({
             message: 'Reloaded'
         });
    }
}

let server = new simpleServer();

When I call the endpoint, the server will output 'Closing server', but the 'Closed server' takes a long time to be called (5 minutes). And when I reload the page, it still works, while the server.listening is equal to false.

I'm using Node.js version 6.0.0 with Express version 4.14.0.


Some updates:

I fixed the issue by calling req.destroy() after sending the response, does this have any side-effects tho?

A cleaner fix would be keeping a record of current connections and closing those in the reload function instead of closing them instantly. This will probably be less heavy if you have a higher load.

Rafael Tavares
  • 5,678
  • 4
  • 32
  • 48
lorenzo373
  • 424
  • 3
  • 19

2 Answers2

11

When you call .close(), it only stops accepting new connections, it does not terminate existing connections.

The reason it may take some time to actually close is if there are existing connections that have set Connection: keep-alive in case of more requests.

mscdex
  • 104,356
  • 15
  • 192
  • 153
  • So the connection stays open, even after I send my response? – lorenzo373 Aug 12 '16 at 08:38
  • 2
    Yes, if `Connection: keep-alive` was requested by the client. It's an HTTP/1.1 feature to reduce the overhead of creating and tearing down a connection for each HTTP request. – mscdex Aug 12 '16 at 09:45
  • @lorenzo373 Related existing question on [force-closing connections](http://stackoverflow.com/questions/14626636/how-do-i-shutdown-a-node-js-https-server-immediately). Joshua Wise has an interesting answer on dealing with keep-alive requests gracefully – Gimby Aug 12 '16 at 10:59
-2

You can use process.exit().

Or you can try

this.server.close(function() {
   console.log('Closed server');
})();
Ayush Mittal
  • 539
  • 2
  • 5