From db24b16e66a63a51e5bacead47ed30c3bf21ff5b Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Fri, 24 Sep 2021 21:14:49 +0300 Subject: [PATCH] feat: gracefully and force shutdown (#3880) --- lib/Server.js | 24 +++++++++++++++++++-- test/server/setupExitSignals-option.test.js | 9 ++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/Server.js b/lib/Server.js index 16d1c428af..44584dd3c7 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -1114,11 +1114,31 @@ class Server { if (this.options.setupExitSignals) { const signals = ["SIGINT", "SIGTERM"]; + let needForceShutdown = false; + + const exitProcess = () => { + // eslint-disable-next-line no-process-exit + process.exit(); + }; + signals.forEach((signal) => { process.on(signal, () => { + if (needForceShutdown) { + exitProcess(); + } + + this.logger.info( + "Gracefully shutting down. To force exit, press ^C again. Please wait..." + ); + + needForceShutdown = true; + this.stopCallback(() => { - // eslint-disable-next-line no-process-exit - process.exit(); + if (typeof this.compiler.close === "function") { + this.compiler.close(exitProcess); + } else { + exitProcess(); + } }); }); }); diff --git a/test/server/setupExitSignals-option.test.js b/test/server/setupExitSignals-option.test.js index 68f8dcafc2..8cd84ed906 100644 --- a/test/server/setupExitSignals-option.test.js +++ b/test/server/setupExitSignals-option.test.js @@ -11,6 +11,7 @@ describe("setupExitSignals option", () => { let exitSpy; let stopCallbackSpy; let stdinResumeSpy; + let closeCallbackSpy; const signals = ["SIGINT", "SIGTERM"]; @@ -36,6 +37,10 @@ describe("setupExitSignals option", () => { .spyOn(process.stdin, "resume") .mockImplementation(() => {}); stopCallbackSpy = jest.spyOn(server, "stopCallback"); + + if (server.compiler.close) { + closeCallbackSpy = jest.spyOn(server.compiler, "close"); + } }); afterEach(async () => { @@ -57,6 +62,10 @@ describe("setupExitSignals option", () => { if (doExit) { expect(stopCallbackSpy.mock.calls.length).toEqual(1); + if (server.compiler.close) { + expect(closeCallbackSpy.mock.calls.length).toEqual(1); + } + clearInterval(interval); resolve();