Created
December 3, 2019 07:21
-
-
Save mike-marcacci/3151559cbfb1f2203b9559d52365b026 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//… | |
// Add readiness endpoint | |
let isShuttingDown = false; | |
app.use( | |
async (ctx, next): Promise<void> => { | |
if (ctx.request.path === "/_ready" || ctx.request.path === "/_ready/") { | |
if (isShuttingDown) { | |
ctx.status = 503; | |
ctx.set("Connection", "close"); | |
ctx.body = "not ready"; | |
return; | |
} | |
ctx.response.body = "ready"; | |
return; | |
} | |
return next(); | |
} | |
); | |
// Add graceful shutdown. | |
process.on("SIGTERM", function gracefulExit(): void { | |
if (isShuttingDown) { | |
console.error( | |
formatLogEntry( | |
new Error("Received second SIGTERM; forceful shutdown initiated."), | |
null, | |
"NOTICE" | |
) | |
); | |
process.exit(1); | |
return; | |
} | |
isShuttingDown = true; | |
console.error( | |
formatLogEntry( | |
new Error("Received SIGTERM; graceful shutdown initiated."), | |
null, | |
"NOTICE" | |
) | |
); | |
// If we're still running after 25 seconds from the signal, force shutdown. | |
setTimeout((): void => { | |
console.error( | |
formatLogEntry( | |
new Error( | |
"Not all connections have closed in time; forceful shutdown initiated." | |
), | |
null, | |
"WARNING" | |
) | |
); | |
process.exit(1); | |
}, 25000); | |
// Kubernetes doesn't wait for service discovery to change before sending the | |
// SIGTERM, so we don't want to immediately close the server to new | |
// connections. We'll immediately start failing readiness checks but continue | |
// to accept new requests for 20 seconds after the signal. | |
setTimeout(async (): Promise<void> => { | |
console.info( | |
formatLogEntry( | |
"Readiness delay complete; continuing graceful shutdown.", | |
null, | |
"NOTICE" | |
) | |
); | |
// Now, 20 seconds after the signal, we will close the server to new | |
// connections, and wait for established connections to close. | |
await Promise.all([ | |
authx.pool.end(), | |
new Promise((resolve): void => void server.close(resolve)) | |
]); | |
console.info( | |
formatLogEntry("Graceful shutdown complete.", null, "NOTICE") | |
); | |
process.exit(0); | |
}, 20000); | |
}); | |
//… |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment