Skip to content

Instantly share code, notes, and snippets.

@justsml
Last active August 18, 2022 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justsml/e3ab099a438b2726862e0e3c913e0d32 to your computer and use it in GitHub Desktop.
Save justsml/e3ab099a438b2726862e0e3c913e0d32 to your computer and use it in GitHub Desktop.
Nodejs snippet to handle `process` events (OS signals) easily with `addSignalListener()`
/**
* Handle process signal events easily with `addSignalListener()`.
*
* Automatically returns a convenient method to unregister your event handler(s), in case you need that functionality.
*
* ## Examples
*
* ```js
* addSignalListener(['SIGINT', 'SIGHUP', 'SIGUSR2'], (signal, event) =>
* console.log(`Process received a signal! ${signal}`, { event });
* );
*
* const removeListener = addSignalListener('SIGINT', (signal) => console.log(`App Interrupted!`));
* removeListener();
*
* addSignalListener(['unhandledRejection', 'uncaughtException'], console.error);
*
* // Specify signals as object keys, where values are ignored and can be used as comments.
* addSignalListener({
* SIGHUP: 1,
* SIGINT: 2,
* SIGUSR2: 15,
* }, (signal, event) => {
* client.close();
* db.close();
* console.log(`Process received a signal! ${signal}`, { event });
* },
* true);
* ```
*
* Returns a cleanup function to remove the listeners that were added.
* @param {number | string | object | number[] | string[] } signals
* @param {function} handler callback
* @param {boolean} onlyOnce default is `false`
*
*/
export const addSignalListener = (
signals,
handler,
onlyOnce,
) => {
signals =
signals && isPrimitive(signals)
? [signals]
: Array.isArray(signals)
? signals
: typeof signals === 'object'
? Object.keys(signals)
: [];
const signalHandlers = {};
signals.forEach((signal) => {
signalHandlers[signal] = (...args) => handler(signal, ...args);
process[onlyOnce ? 'once' : 'on'](signal, signalHandlers[signal]);
});
// Return a cancel function that will remove the listeners
return () =>
signals.forEach((signal) => process.off(signal, signalHandlers[signal]));
};
const isPrimitive = (value) =>
typeof value === 'string' ||
typeof value === 'number' ||
typeof value === 'boolean' ||
typeof value === 'symbol' ||
typeof value === 'undefined' ||
value === null;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment