@routes/graceful-shutdown
π Shut down server gracefully
net.Server or Express, whatever you're using should be fine
const graceful = require('@routes/graceful-shutdown');
const server = app.listen(1337); // express will return the server instance here
graceful(server);
Arguments
- First argument is an net.Server instance (including Express server)
- Second argument is options:
option | type | meaning | default |
---|---|---|---|
timeout |
Number | Time (in milliseconds) to wait before forcefully shutting down |
10000 (10 sec) |
logger |
Object | Object with info and error functions (supports async loggers). Pass false to disable |
console |
events |
Array | Process events to handle | ['SIGTERM', 'SIGINT'] |
onsuccess |
Function | Final functionality when shutdown finished correctly | process.exit(0) |
onfail |
Function | Final functionality when shutdown finished incorrectly | process.exit(1) |
Example of using options
graceful(server, {
timeout: 3e4,
logger: winston.createLogger({level: 'error'}),
});
What happens on process termination?
- Process termination is interrupted
- Open connections are instructed to end (FIN packet) and receive a new timeout to allow them to close in time
- The server is firing a close function
- After correct closing:
onsuccess
(default: process exists with exit code 0)- End correct behaviour
- After
timeout
passes - an error log is printed with the amount of connection that will be forcefully terminated -
onfail
: (default: process exists with an exit code 1)
Add custom functionality to shutdown
Add behaviour to the graceful shut down process using a built in pub/sub mechanism
const { sub, BEFORE, AFTER } = graceful(server, {...});
// Will be triggered first thing before the procedure starts
sub(BEFORE, async() => {
await flushThrottledThings();
await closeDatabaseConnections();
});
// Will be triggered once the procedure has ended
sub(AFTER, () => logger.info('Okay okay, closing down'));
server.shuttingDown
After shutdown has initiated, the attribute shuttingDown
is attached to server with value of true
.
User can query this value on service to know not to send any more requests to the service
app.get(
'/health',
(request, response) => response.status(server.shuttingDown ? 503 : 200).end()
);
What else does graceful expose?
-
{Set} sockets
A reference to the sockets collection
const { sockets } = graceful(server, {...});
// Monitor size of set every two minutes
setInterval(() => stats.time('graceful_stored_sockets', sockets.size), 12e4);