You can implement middleware that immediately rejects incoming connections as soon as you start your shutdown process.
// set this flag to true when you want to start
// immediately rejecting new connections
let pendingShutdown = false;
// first middleware
app.use((req, res, next) => {
if (pendingShutdown) {
// immediately reject the connection
res.sendStatus(503);
} else {
next();
}
});
With no long running connections as soon as the ones that were in process finish, the server should find a natural exit point when you do this:
pendingShutdown = true;
server.close();
There are also a few modules on NPM that provide various algorithms for shut-down too.
Then, to prevent any long lived stuck connections from preventing your server from shutting down, you can either set a timeout on the existing connections or just set a global timeout and do a process.exit()
after your timeout (to force shutdown).