diff --git a/CHANGELOG.md b/CHANGELOG.md index f49126e3..4a950e0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ # `@bedrock/core` ChangeLog -## 6.2.0 - 2023-xx-xx +## 6.2.0 - 2024-xx-xx ### Added -- Add documentation for `bedrock.stop` and `bedrock.exit` events. +- Add `bedrock.shutdown()` call that performs an orderly shutdown and emits + various events. This differs from `exit()` and `process.exit()` which are + more immediate. +- Add `bedrock.stopped` event, emitted before `bedrock.exit`. +- Add documentation for `bedrock.stop`, `bedrock.stopped`, and `bedrock.exit` + events. ### Changed - Deprecate undocumented `bedrock-cli.exit` event. Use `bedrock.exit`. If there diff --git a/README.md b/README.md index 4967e767..5731f2ce 100644 --- a/README.md +++ b/README.md @@ -649,6 +649,10 @@ event or causes the application to exit early. the event modules should use to stop services for a clean shutdown and to emit any custom events they would like to make available to their dependents. +- **bedrock.stopped** + - Emitted while exiting, and after `bedrock.stop` if process was previously + in a started state. External access to web services or other features + provided by modules should now be unavailable. - **bedrock.exit** - Emitted immediately before exiting. diff --git a/lib/index.js b/lib/index.js index 8f110119..76ed8e79 100644 --- a/lib/index.js +++ b/lib/index.js @@ -234,14 +234,24 @@ export async function runOnce(id, fn, options = {}) { } /** - * Called from a worker to exit gracefully and without an error code. Typically - * used by subcommands. Use `process.exit(1)` (or other error code) to exit - * with an error code. + * Called from a worker to exit immediately and without an error code. + * Typically used by subcommands. Use `process.exit(1)` (or other error code) + * to exit with an error code. Use `shutdown` to perform an orderly exit. */ export function exit() { cluster.worker.kill(); } +/** + * Called from a worker to exit gracefully and without an error code. Typically + * used by subcommands. Use `process.exit(1)` (or other error code) to exit + * with an error code. Use `exit()` to exit immediately. This call will emit + * events for an orderly shutdown. + */ +export async function shutdown() { + await _exit(); +} + async function _waitForOneMessage({type, id}) { // get coordinated message from primary return new Promise(resolve => { @@ -720,7 +730,7 @@ async function _preparePrimaryExit() { } } -async function _exit(code) { +async function _exit(code = 0) { /* Notes on exiting: When the primary does an orderly exit, it must notify all workers @@ -754,13 +764,18 @@ async function _exit(code) { if(BEDROCK_STARTED) { await events.emit('bedrock.stop'); } + await events.emit('bedrock.stopped'); // FIXME: deprecated in v6.x, remove in v7+ await events.emit('bedrock-cli.exit'); await events.emit('bedrock.exit'); } } finally { - await _logExit(code); - process.exit(code); + if(cluster.isPrimary) { + await _logExit(code); + process.exit(code); + } else { + cluster.worker.kill(); + } } } @@ -771,10 +786,7 @@ async function _exitOnError(err) { } } -async function _logExit(code = 0) { - if(!cluster.isPrimary) { - return; - } +async function _logExit(code) { // log final message and wait for logger to flush const logger = loggers.get('app').child('bedrock/primary'); try {