From db00bdcf1a438d83455da30440253ffe19dfd64e Mon Sep 17 00:00:00 2001 From: carpie Date: Tue, 10 Apr 2018 17:49:47 -0400 Subject: [PATCH] Exit process cleanly on SIGINT, SIGTERM, and SIGUSR2 signals --- src/postcss-server.js | 14 ++++++++++---- test/postcss-server.js | 44 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/postcss-server.js b/src/postcss-server.js index 30d0946..aacfdd7 100644 --- a/src/postcss-server.js +++ b/src/postcss-server.js @@ -121,15 +121,21 @@ const main = async function main( fs.unlinkSync(socketPath); // eslint-disable-line no-sync }; + const termHandler = () => { + process.exit(0); + }; + server.on('close', () => { process.removeListener('exit', handler); - process.removeListener('SIGINT', handler); - process.removeListener('SIGTERM', handler); + process.removeListener('SIGINT', termHandler); + process.removeListener('SIGTERM', termHandler); + process.removeListener('SIGUSR2', termHandler); }); process.on('exit', handler); - process.on('SIGINT', handler); - process.on('SIGTERM', handler); + process.on('SIGINT', termHandler); + process.on('SIGTERM', termHandler); + process.on('SIGUSR2', termHandler); resolve(); }); diff --git a/test/postcss-server.js b/test/postcss-server.js index 18334ea..980c49a 100644 --- a/test/postcss-server.js +++ b/test/postcss-server.js @@ -66,9 +66,17 @@ describe('postcss-server', () => { }); describe('main(...testArgs)', () => { - let signintHandlers; + let exitHandlers, exitStub, signintHandlers, sigtermHandlers, + sigusr2Handlers; - beforeEach(() => { signintHandlers = process.listeners('SIGINT'); }); + beforeEach(() => { + exitHandlers = process.listeners('exit'); + signintHandlers = process.listeners('SIGINT'); + sigtermHandlers = process.listeners('SIGTERM'); + sigusr2Handlers = process.listeners('SIGUSR2'); + exitStub = stub(process, 'exit'); + }); + afterEach(() => { process.exit.restore(); }); beforeEach(invokeMain); afterEach(closeServer); @@ -77,13 +85,43 @@ describe('postcss-server', () => { expect(server.address()).to.eql(testSocket); }); - it('observes SIGINT to cleanup server socket', () => { + it('observes SIGINT to exit the process', () => { const newHandlers = process.listeners('SIGINT') .slice(signintHandlers.length); expect(newHandlers.length).to.eql(1); newHandlers[0](); + expect(exitStub).to.have.been.called; + }); + + it('observes SIGTERM exit the process', () => { + const newHandlers = process.listeners('SIGTERM') + .slice(sigtermHandlers.length); + + expect(newHandlers.length).to.eql(1); + newHandlers[0](); + + expect(exitStub).to.have.been.called; + }); + + it('observes SIGUSR2 exit the process', () => { + const newHandlers = process.listeners('SIGUSR2') + .slice(sigusr2Handlers.length); + + expect(newHandlers.length).to.eql(1); + newHandlers[0](); + + expect(exitStub).to.have.been.called; + }); + + it('uses the exit handler to clean up the server socket', () => { + const newHandlers = process.listeners('exit') + .slice(exitHandlers.length); + + expect(newHandlers.length).to.eql(1); + newHandlers[0](); + expect(fs.existsSync(testSocket)).to.be.false; });