From b539fb74237e967d315a3bf08c34e5ab7215a626 Mon Sep 17 00:00:00 2001 From: "Alex A." <45429049+alatras@users.noreply.github.com> Date: Tue, 26 May 2026 17:29:36 +0200 Subject: [PATCH] fix: handle shutdown before worker activation --- index.js | 19 ++++--------------- lib/shutdown.js | 24 ++++++++++++++++++++++++ test/unit.test.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 lib/shutdown.js diff --git a/index.js b/index.js index d8bae45..0c9511f 100644 --- a/index.js +++ b/index.js @@ -18,21 +18,10 @@ const cmd = require('yargs') .argv const hnd = require('./lib/worker.js')(cmd) +const createShutdownHandler = require('./lib/shutdown') -let shutdown = 0 -process.on('SIGINT', () => { - if (shutdown) { - return - } - shutdown = 1 - - if (!hnd.active) { - return - } - console.log('BKW', process.title, 'shutting down') - hnd.stop(() => { - process.exit() - }) -}) +const shutdown = createShutdownHandler(hnd) +process.on('SIGINT', shutdown) +process.on('SIGTERM', shutdown) module.exports = hnd diff --git a/lib/shutdown.js b/lib/shutdown.js new file mode 100644 index 0000000..dffdf82 --- /dev/null +++ b/lib/shutdown.js @@ -0,0 +1,24 @@ +'use strict' + +function createShutdownHandler (hnd, exit = process.exit, log = console.log) { + let shutdown = 0 + + return () => { + if (shutdown) { + return + } + shutdown = 1 + + if (!hnd.active) { + exit(0) + return + } + + log('BKW', process.title, 'shutting down') + hnd.stop(() => { + exit(0) + }) + } +} + +module.exports = createShutdownHandler diff --git a/test/unit.test.js b/test/unit.test.js index 5041a09..655a76d 100644 --- a/test/unit.test.js +++ b/test/unit.test.js @@ -6,6 +6,7 @@ const path = require('path') const fs = require('fs') const worker = require('../lib/worker') +const createShutdownHandler = require('../lib/shutdown') const fixtureWorker = path.join(__dirname, 'fixtures', 'workers', 'dummy.js') async function setupDir (t) { @@ -103,3 +104,47 @@ test('config priority order', async (t) => { t.is(wrk.conf.source, 'env-json') }) }) + +test('shutdown handler', async (t) => { + await t.test('exits immediately when worker is not active', (t) => { + let exitCode = null + let stopCalled = false + const hnd = { + active: 0, + stop: () => { + stopCalled = true + } + } + + const shutdown = createShutdownHandler(hnd, code => { + exitCode = code + }, () => {}) + + shutdown() + + t.is(stopCalled, false) + t.is(exitCode, 0) + }) + + await t.test('stops active worker once before exiting', (t) => { + let exitCode = null + let stopCalls = 0 + const hnd = { + active: 1, + stop: cb => { + stopCalls++ + cb() + } + } + + const shutdown = createShutdownHandler(hnd, code => { + exitCode = code + }, () => {}) + + shutdown() + shutdown() + + t.is(stopCalls, 1) + t.is(exitCode, 0) + }) +})