Last active
October 17, 2024 19:42
-
-
Save Dante-101/de2fbd5071bec0c0647f5c9fa1cfa179 to your computer and use it in GitHub Desktop.
Gist for graceful shutdown of workers
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
| gracefulClusterShutdown = (signal: NodeJS.Signals) => async () => { | |
| if (this.shutdownInProgress) | |
| return | |
| this.shutdownInProgress = true | |
| this.hasCleanWorkerExit = true | |
| log.info(`Got ${signal} on ${this.processStr}. Graceful shutdown start at ${new Date().toISOString()}`) | |
| try { | |
| if (cluster.isMaster) { | |
| await this.shutdownWorkers(signal) | |
| log.info(`${this.processStr} - worker shutdown successful`) | |
| } | |
| await this.stop() //stop yourself after the workers are shutdown if you are master | |
| log.info(`${this.processStr} shutdown successful`) | |
| logAndExit(this.hasCleanWorkerExit ? 0 : 1) | |
| } catch (e) { | |
| logAndExit(1) | |
| } | |
| } | |
| shutdownWorkers = (signal: NodeJS.Signals) => { | |
| return new Promise<void>((resolve, reject) => { | |
| if (!cluster.isMaster) { return resolve() } | |
| const wIds = Object.keys(cluster.workers) | |
| if (wIds.length == 0) { return resolve() } | |
| //Filter all the valid workers | |
| const workers = wIds.map(id => cluster.workers[id]).filter(v => v) as cluster.Worker[] | |
| let workersAlive = 0 | |
| let funcRun = 0 | |
| //Count the number of alive workers and keep looping until the number is zero. | |
| const fn = () => { | |
| ++funcRun | |
| workersAlive = 0 | |
| workers.forEach(worker => { | |
| if (!worker.isDead()) { | |
| ++workersAlive | |
| if (funcRun == 1) | |
| //On the first execution of the function, send the received signal to all the workers | |
| worker.kill(signal) | |
| } | |
| }) | |
| log.info(workersAlive + " workers alive") | |
| if (workersAlive == 0) { | |
| //Clear the interval when all workers are dead | |
| clearInterval(interval) | |
| return resolve() | |
| } | |
| } | |
| const interval = setInterval(fn, 500) | |
| }) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment