Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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>');
})
Comment thread
rxmarbles marked this conversation as resolved.
Outdated
Copy link

Copilot AI Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon after the server creation function. Add a semicolon at the end of line 55.

Suggested change
})
});

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply commit suggestion

Comment thread
rxmarbles marked this conversation as resolved.
Outdated

createTerminus(serverWithSignalParam, optionsWithSignalParam);

serverWithSignalParam.listen(3001);