Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ npm i @godaddy/terminus --save
const http = require('http');
const { createTerminus } = require('@godaddy/terminus');

function onSignal () {
function onSignal (signal) {
console.log('server is starting cleanup');
console.log('received signal:', signal);
return Promise.all([
// your clean logic, like closing database connections
]);
Expand Down Expand Up @@ -68,7 +69,7 @@ const options = {
useExit0, // [optional = false] instead of sending the received signal again without beeing catched, the process will exit(0)
sendFailuresDuringShutdown, // [optional = true] whether or not to send failure (503) during shutdown
beforeShutdown, // [optional] called before the HTTP server starts its shutdown
onSignal, // [optional] cleanup function, returning a promise (used to be onSigterm)
onSignal, // [optional] cleanup function, returning a promise (used to be onSigterm). Receives signal as parameter.
onShutdown, // [optional] called right before exiting
onSendFailureDuringShutdown, // [optional] called before sending each 503 during shutdowns

Expand Down
38 changes: 38 additions & 0 deletions example/signal-parameter-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict'

const http = require('http')
const { createTerminus } = require('@godaddy/terminus')

// Create basic HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('Server is running\n')
})

// Set up graceful shutdown with signal parameter
createTerminus(server, {
signal: 'SIGTERM',
onSignal: (signal) => {
console.log(`Received signal: ${signal}`)
console.log('Starting graceful shutdown...')

// You can now track which signal triggered the shutdown
// for observability and monitoring purposes
if (signal === 'SIGTERM') {
console.log('Shutting down due to SIGTERM (likely from process manager)')
} else if (signal === 'SIGINT') {
console.log('Shutting down due to SIGINT (likely from Ctrl+C)')
}

return Promise.resolve()
},
onShutdown: () => {
console.log('Server shutdown complete')
return Promise.resolve()
}
})

server.listen(3000, () => {
console.log('Server listening on port 3000')
console.log('Send SIGTERM or SIGINT to trigger graceful shutdown')
})
16 changes: 16 additions & 0 deletions lib/standalone-tests/terminus.onsignal.with-signal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))

const { createTerminus } = require('../../')

createTerminus(server, {
onSignal: (signal) => {
console.log('on-signal-runs:' + signal)
return Promise.resolve()
}
})

server.listen(8000, () => {
process.kill(process.pid, 'SIGTERM')
})
18 changes: 18 additions & 0 deletions lib/standalone-tests/terminus.onsignal.with-signal.multiple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'
const http = require('http')
const server = http.createServer((req, res) => res.end('hello'))

const { createTerminus } = require('../../')
const SIGNAL = process.argv[2] || 'SIGTERM'

createTerminus(server, {
signal: SIGNAL,
onSignal: (signal) => {
console.log('on-signal-runs:' + signal)
return Promise.resolve()
}
})

server.listen(8000, () => {
process.kill(process.pid, SIGNAL)
})
2 changes: 1 addition & 1 deletion lib/terminus.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ function decorateWithSignalHandler (server, state, options) {
try {
await beforeShutdown()
await asyncServerStop()
await onSignal()
await onSignal(signal)
await onShutdown()
if (useExit0) {
// Exit process
Expand Down
15 changes: 15 additions & 0 deletions lib/terminus.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,21 @@ describe('Terminus', () => {
expect(result.stdout.toString().trim()).to.eql('on-sigusr2-runs\non-shutdown-runs')
})

it('passes signal parameter to onSignal function when killed with SIGTERM', () => {
const result = spawnSync('node', ['lib/standalone-tests/terminus.onsignal.with-signal.js'])
expect(result.stdout.toString().trim()).to.eql('on-signal-runs:SIGTERM')
})

it('passes signal parameter to onSignal function when killed with SIGINT', () => {
const result = spawnSync('node', ['lib/standalone-tests/terminus.onsignal.with-signal.multiple.js', 'SIGINT'])
expect(result.stdout.toString().trim()).to.eql('on-signal-runs:SIGINT')
})

it('passes signal parameter to onSignal function when killed with SIGUSR2', () => {
const result = spawnSync('node', ['lib/standalone-tests/terminus.onsignal.with-signal.multiple.js', 'SIGUSR2'])
expect(result.stdout.toString().trim()).to.eql('on-signal-runs:SIGUSR2')
})

it('manages multiple servers', () => {
const result = spawnSync('node', ['lib/standalone-tests/terminus.multiserver.js'])
expect(result.stdout.toString().trim()).to.eql([
Expand Down
2 changes: 1 addition & 1 deletion typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ declare module "@godaddy/terminus" {
statusError?: number,
statusErrorResponse?: Record<string, unknown>,
useExit0?: boolean,
onSignal?: () => Promise<any>;
onSignal?: (signal?: string) => Promise<any>;
onSendFailureDuringShutdown?: () => Promise<any>;
onShutdown?: () => Promise<any>;
beforeShutdown?: () => Promise<any>;
Expand Down
20 changes: 20 additions & 0 deletions typings/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,23 @@ const options: TerminusOptions = {
createTerminus(server, options);

server.listen(3000);

// Test new signal parameter feature
async function onSignalWithParam(signal?: string) {
console.log('server is starting cleanup for signal:', signal);
return Promise.resolve();
}

const optionsWithSignalParam: TerminusOptions = {
onSignal: onSignalWithParam,
onShutdown,
logger: console.log
};

const serverWithSignalParam = http.createServer((request, response) => {
response.end('<html><body><h1>Hello, World!</h1></body></html>');
});

createTerminus(serverWithSignalParam, optionsWithSignalParam);

serverWithSignalParam.listen(3001);