diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1345131 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# OS X files +.DS_Store + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules diff --git a/README.md b/README.md index e44bfca..354cfbc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,49 @@ # node-cleanup + installs a cleanup handler that always runs on exiting node + +## Installation + +``` +npm install node-cleanup --save +``` + +## Usage + +nodeCleanup() installs a function that performs cleanup activities just before the node process exits. The cleanup function runs when the process exits normally, when the user presses *ctrl*-C, and when an exception is uncaught. The caller may specify the termination messages to use. + +```js +var nodeCleanup = require('node-cleanup'); + +nodeCleanup(function () { + // release resources here before node exits +}); +``` + +nodeCleanup() also ensures that ctrl-C is handled gracefully in contexts that already have exit handlers installed, such as Node Express. To receive just this benefit, the caller need not provide a cleanup handler. + +By default, `nodeCleanup()` writes `[ctrl-C]` to `stderr` when interrupted and `Uncaught exception...` to `stderr` when an uncaught exception occurs. You may override either or both of these values in a second parameter: + +```js +var nodeCleanup = require('node-cleanup'); + +nodeCleanup(function () { + // release resources here before node exits +}, { ctrl_C: '^C' }); +``` + +## Reference + +`nodeCleanup(cleanupHandler, messages)` + +Install a cleanup handler that reliably runs when node exits. Both parameters are optional. Calling `nodeCleanup()` without a `cleanupHandler` still provides the benefit of ensuring that other installed exit handlers run on *ctrl*-C. + +| Param | Description | +| --- | --- | +| cleanupHandler | A function that performs the final cleanup of resources before the node process exits. The function may write to `stderr` and `stdout`. It takes no parameters and can't abort the exit. The handler is optional, defaulting to a function that does nothing. | +| messages | An optional object mapping any of the keys `ctrl_C` and `uncaughtException` to the message strings that output to stderr. Set a message to the empty string `''` to prevent output to `stderr` for its case. Default messages are provided omitted messages. | + +## Credit + +This code was borrowed and modified from [CanyonCasa](http://stackoverflow.com/users/3319552/canyoncasa)'s answer to a stackoverflow question. I found the code necessary for all my node projects. See [the stackoverflow answer](http://stackoverflow.com/a/21947851/650894) for more examples of use. + diff --git a/node-cleanup.js b/node-cleanup.js new file mode 100644 index 0000000..a931760 --- /dev/null +++ b/node-cleanup.js @@ -0,0 +1,61 @@ +/** + * nodeCleanup() installs a function that performs cleanup activities just + * before the node process exits. The cleanup function runs when the process + * exits normally, when the user presses ctrl-C, and when an exception is + * uncaught. The caller may specify the termination messages to use. + * + * nodeCleanup() also ensures that ctrl-C is handled gracefully in contexts + * that already have exit handlers installed, such as Node Express. To + * receive just this benefit, the caller need not provide a cleanup handler. + * + * This code was borrowed and modified from CanyonCasa's answer to a + * stackoverflow question. I found the code necessary for all my node + * projects. See the stackoverflow answer for example usage: + * http://stackoverflow.com/a/21947851/650894 + * + * @param cleanupHandler A function that performs the final cleanup of + * resources before the node process exits. The function may write to + * stderr and stdout. It takes no parameters and can't abort the exit. + * The handler is optional, defaulting to a function that does nothing. + * @param messages An optional object mapping any of the keys `ctrl_C` and + * `uncaughtException` to the message strings that output to stderr. + * Set a message to the empty string '' to prevent output to stderr + * for its case. Default messages are provided omitted messages. + */ + +module.exports = function nodeCleanup(cleanupHandler, messages) { + + messages = messages || {}; + if (typeof messages.ctrl_C !== 'string') + messages.ctrl_C = '[ctrl-C]'; + if (typeof messages.uncaughtException !== 'string') + messages.uncaughtException = 'Uncaught exception...'; + + // attach user callback to the process event emitter. + // if no callback, it will still exit gracefully on Ctrl-C + cleanupHandler = cleanupHandler || noOp; + process.on('cleanup', cleanupHandler); + + // do app-specific cleaning before exiting + process.on('exit', function () { + process.emit('cleanup'); + }); + + // catch ctrl+c event and exit normally + process.on('SIGINT', function () { + if (messages.ctrl_C !== '') + process.stderr.write(messages.ctrl_C + "\n"); + process.exit(2); + }); + + //catch uncaught exceptions, trace, then exit normally + process.on('uncaughtException', function(e) { + if (messages.uncaughtException !== '') { + process.stderr.write(messages.uncaughtException + "\n"); + process.stderr.write(e.stack + "\n"); + } + process.exit(99); + }); +}; + +function noOp() {}; // for just the benefit of graceful SIGINTs diff --git a/package.json b/package.json new file mode 100644 index 0000000..8773ae1 --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "node-cleanup", + "version": "1.0.0", + "description": "installs a cleanup handler that always runs on exiting node", + "main": "node-cleanup.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jtlapp/node-cleanup.git" + }, + "keywords": [ + "node", + "exit", + "cleanup", + "sigint", + "ctrl-c" + ], + "author": "", + "contributors": [ + { + "name": "CanyonCasa", + "url": "http://stackoverflow.com/users/3319552/canyoncasa" + }, + { + "name": "Joseph T. Lapp", + "email": "arachnojoe@gmail.com", + "url": "http://josephtlapp.com" + } + ], + "bugs": { + "url": "https://github.com/jtlapp/node-cleanup/issues" + }, + "homepage": "https://github.com/jtlapp/node-cleanup#readme" +}