The library provides the resources to implement graceful shutdown with kubernetes.
MIT License
The library provides the resources to implement graceful shutdown with kubernetes.
When running microservices in kubernetes. We need to handle the termination signals emitted by kubernets. The proper way of doing this is to:
The library makes the process mentioned above easy. Just register your graceful shutdown hook and add a grace period.
Note that your grace period must be lower than the grace period defiend in kubernetes!
For example, using the Express framework:
import { Response, Request } from 'express'
import express from 'express'
import { addGracefulShutdownHook, getHealthHandler, shutdown } from '@neurocode.io/k8s-graceful-shutdown'
const app = express()
app.disable('x-powered-by')
const port = process.env.PORT || 3000
const server = app.listen(port, () => console.log(`App is running on http://localhost:${port}`))
// Patch NodeJS server close function with a proper close that works as you might expect closing keep-alive connections for you!
// Read here for more info https://github.com/nodejs/node/issues/2642
server.close = shutdown(server)
const healthy = (req: Request, res: Response) => {
res.send('everything is great')
}
const notHealthy = (req: Request, res: Response) => {
res.status(503).send('oh no, something bad happened!')
}
const healthTest = async () => {
// this is optional
// you can use it to conduct healthChecks
return true
}
const healthCheck = getHealthHandler({ healthy, notHealthy, test: healthTest })
app.get('/health', healthCheck)
const sleep = (time: number) => new Promise((resolve) => setTimeout(resolve, time))
const asyncOperation = async () => sleep(3000).then(() => console.log('Async op done'))
const closeServers = async () => {
await asyncOperation() // can be any async operation such as mongo db close, or send a slack message ;)
server.close()
}
const gracePeriodSec = 5*1000
addGracefulShutdownHook(gracePeriodSec, closeServers)
server.addListener('close', () => console.log('shutdown after graceful period'))
The simple app shown above, adds a graceful shutdown period of 5 seconds after which the hook, which takes care of closing the server with the help of our shutdown functionality, gets triggered. Upon sending a SIGINT or SIGTERM signal, the user can see that a grace period of 5 seconds after which a waiting async operation of 3 seconds takes place, and only then the message 'shutdown after graceful period' indicating the closing of the server will be displayed.
The app also showcases the functionality of the "getHealthHandler". Upon requesting localhost:3000/health, the healthTest will return true and the message 'everything is great' indicating a positive health check should be displayed. The user can change the healthTest to return false, and watch the message change into 'oh no, something bad happened!' indicating an unhealthy state.
If you use the Koa framework check out the demos/ folder. We have a Koa example with a similar functionality to the app shown above. The Koa app uses getHealthContextHandler with fn(ctx) support for the healthy and notHealthy handlers, instead of getHealthHandler which takes healthy and notHealthy handlers as fn(req, res).
An example of how the fraceful shutdown workflow works: