From 5165e974381d0d41e77047373b72a8e60241f1f4 Mon Sep 17 00:00:00 2001 From: Guillaume Quittet Date: Mon, 24 Jun 2024 16:34:54 +0200 Subject: [PATCH 1/2] refactor: remove unused shutdown.ts --- src/util/shutdown.ts | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/util/shutdown.ts diff --git a/src/util/shutdown.ts b/src/util/shutdown.ts deleted file mode 100644 index 393e953..0000000 --- a/src/util/shutdown.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type improvedServer from "#core/improvedServer"; -import type { ICore } from "#interface/core"; -import config from "#config/index"; -import State from "#core/state"; -import sleep from "#util/sleep"; - -const shutdown = - >(server: TServer, parent: ICore) => - async (type: string, value: number, body?: Error) => { - const { timeout, closePromises } = config; - - const error: Error = body && body.message ? body : new Error(type); - - parent.status.set(State.SHUTTING_DOWN, error); - - await sleep(timeout); - - await Promise.all(closePromises.map((closePromise) => closePromise())); - await server.stop(); - - parent.status.set(State.SHUTDOWN, error); - - process.exit(128 + value); - }; - -export default shutdown; From db956e850ef897f57daa9143d5c3ff19780003a3 Mon Sep 17 00:00:00 2001 From: Guillaume Quittet Date: Mon, 24 Jun 2024 16:36:22 +0200 Subject: [PATCH 2/2] feat: add ability to have sync close * Add syncClose boolean option Issue: #27 --- README.md | 3 ++- src/config/index.ts | 1 + src/core/improvedServer.ts | 12 +++++++++--- src/interface/gracefulServerOptions.ts | 1 + src/interface/options.ts | 1 + 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 158e024..5b48e44 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,8 @@ where `State` is an enum that contains, `STARTING`, `READY`, `SHUTTING_DOWN` and All of the below options are optional. | Name | Type | Default | Description | -| ----------------- | :------------------------: | :-----: | ---------------------------------------------------------------: | +|-------------------|:--------------------------:|:-------:|-----------------------------------------------------------------:| +| syncClose | boolean | false | Run the closePromises in a series. | | closePromises | (() => Promise)[] | [] | The functions to run when the API is stopping | | timeout | number | 1000 | The time in milliseconds to wait before shutting down the server | | healthCheck | boolean | true | Enable/Disable the default endpoints (liveness and readiness) | diff --git a/src/config/index.ts b/src/config/index.ts index ba0ac5f..060d9c1 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -2,6 +2,7 @@ import type { IGracefulServerOptions } from "#interface/gracefulServerOptions"; import type { IOptions } from "#interface/options"; const options: IOptions = { + syncClose: false, closePromises: [], timeout: 1000, healthCheck: true, diff --git a/src/core/improvedServer.ts b/src/core/improvedServer.ts index 5e66956..8ecfe4d 100644 --- a/src/core/improvedServer.ts +++ b/src/core/improvedServer.ts @@ -74,7 +74,7 @@ const improvedServer = (server: TServer, serverStatus: I stopping = true; - const { timeout, closePromises } = config; + const { timeout, closePromises, syncClose } = config; let error: Error | undefined; if (args.body && args.body.message) { @@ -87,14 +87,20 @@ const improvedServer = (server: TServer, serverStatus: I await sleep(timeout); - await Promise.all(closePromises.map((closePromise) => closePromise())); + if (syncClose) { + for (const closePromise of closePromises) { + await closePromise(); + } + } else { + await Promise.allSettled(closePromises.map((closePromise) => closePromise())); + } server.removeAllListeners("request"); server.on("request", (_: http.IncomingMessage, res: http.ServerResponse) => { if (!res.headersSent) res.setHeader("connection", "close"); }); - await Promise.all([socketsPool.closeAll(), secureSocketsPool.closeAll()]); + await Promise.allSettled([socketsPool.closeAll(), secureSocketsPool.closeAll()]); await new Promise((resolve, reject) => { server.close((err) => { diff --git a/src/interface/gracefulServerOptions.ts b/src/interface/gracefulServerOptions.ts index c96a270..0b75b31 100644 --- a/src/interface/gracefulServerOptions.ts +++ b/src/interface/gracefulServerOptions.ts @@ -1,4 +1,5 @@ export type IGracefulServerOptions = { + syncClose?: boolean; closePromises?: (() => Promise)[]; timeout?: number; healthCheck?: boolean; diff --git a/src/interface/options.ts b/src/interface/options.ts index 0fcfc0f..282a715 100644 --- a/src/interface/options.ts +++ b/src/interface/options.ts @@ -1,4 +1,5 @@ export type IOptions = { + syncClose: boolean; closePromises: (() => Promise)[]; timeout: number; healthCheck: boolean;