npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grace

v0.2.5

Published

Graceful application with domains, cluster, error handling and Express support

Downloads

11

Readme

grace

Node.js project

Warning

Because it's pretty hard to write concurrent code, treat with the master and the workers, overriding source code, supporting Windows and Linux and writing a transparent API, this module is in a beta state until it reaches v1.0.0.

It's working pretty well with the provided examples and is actively tested in edge cases. If you find a bug, please report it.


Graceful shutdown/restart with domains and cluster support

Version: 0.1.4

Provides an event-based mechanism to start and gracefully shutdown a Node.js process when a SIGINT signal is sent to it. Because Windows doesn't have POSIX signals a different method has to be used (reading the stdin for a ctrl-c key). The process can be gracefully killed pressing ctrl-c (Windows & Linux) and sending to it a SIGINT signal (Linux). It also uses domains so uncaught exceptions doesn't kill the process. Furthermore, if you use workers, the shutdown task takes care about that and transparently manages them in order to always guarantee a graceful shutdown providing to the user a last opportunity to clean up tasks asynchronously.

If the process finishes correctly the exit code is 0, otherwise 1. The process can also exit with a custom code.

Installation

npm install graceful-shut

Example

var gs = require ("graceful-shut");

var app = gs.create ();

app.on ("error", function (error){
	//Unhandled and redirected errors
	console.error (error);
});

app.on ("start", function (){
	//On Windows shutdown() must be called in order to call the shutdown listener
	//and exit. On Linux is not needed to finish the process but the shutdown
	//listener won't be called. Therefore, if you want to always call the shutdown
	//listener, always call to shutdown().
	app.shutdown ();
});

app.on ("shutdown", function (cb){
	//Clean up tasks
	cb ();
});

app.on ("exit", function (code){
	console.log ("bye (" + code + ")");
});

app.timeout (1000, function (cb){
	//The timeout is used if the shutdown task takes more time than expected
	//The callback must be always called 
	console.error ("forced shutdown!");
	cb ();
});

app.start ();

Methods and Properties

Take a look at the examples to fully understand how to use a "graceful application" -especially with clusters-. Once you feel comfortable with it you probably will never stop using it.

gs.create()
Creates a "graceful application" that emits error, start and shutdown events. Only one "graceful application" can be created per Node.js process.

Grace#dom()
Returns the domain used internally that is listenig for errors. Useful when you want to use Domain#intercept() or Domain#bind() to redirect errors to the internal domain.

Grace#redirectError(error)
Redirects the error to the error event listener.

Grace#shutdown([exitCode])
Programatically shutdowns the Node.js process. The listener attached to the shutdown event will be called before shutting down the process. On Windows this function must be called in order to shutdown the process even if there's no pending events in the event loop queue because the process is continuously reading the stdin. On Linux it's not needed to call it when the event loop is emty because the process automatically finishes, but the shutdown listener is not called, so for compatibility and reusability of the same code on different platforms it's recommended to always call to shutdown() both on Windows and Linux when you want exit.

Calling to process.exit() will exit your application without calling the shutdown listener. Use it if you want to exit immediately but I recommend to always call to the shutdown() function and set a timeout to give an opportunity to gracefully shutdown before forcing the exit. So, if you want to exit, use Grace#shutdown() instead of process.exit().

If you use workers they're managed for you so you don't need to worry if a worker hangs up when shutting down the server (probably by one or more active long living connections), just set a timeout and it will be killed.

The listener runs inside a domain. Unhandled exceptions will be handled by the error event.

Grace#start()
Starts the "graceful application". The listener runs inside a domain. Unhandled exceptions will be handled by the error event. The only exceptions that can kill the process when the server is up and listening for new connections are those that are produced synchronously at compile-time when initializing the server. These errors are not considered "pure uncaught exceptions", they're produced during the server initialization. Therefore, uncaught exceptions thrown by a user request will never kill the entire server, that's for sure.

Grace#timeout(ms[, callback])
Adds a timeout in milliseconds to wait before forcing the exit the shutdown task takes more than expected. By default there's no timeout so the master/workers can hang up and there won't be any way to finish the process, you'll need to send a SIGINT signal or press ctrl-c. It's strongly recommended to always configure a timeout.

An optional callback can be passed. It will be executed when the exit has been forced. The callback receives a function that must be executed to completely finish the process. This callback it's only for informational purposes like printing to console. It's up to you if you do any asynchronous calls like sending an email to the administrator or whatever, but make sure to always call the on completion callback or the process will never end.

Events

error
Emitted when an unhandled exception has been thrown or has been redirected to the domain with Domain#intercept() or Domain#bind(). Exceptions thrown inside this listener will kill the process, be careful.

exit
Emitted when the process is going to die. The event loop doesn't work at this point so asynchronous tasks won't work. Tipically used to print something in console. The exit code is passed as a parameter.

shutdown
Emitted when the Node.js process is going to finalize. This is the last chance to gracefully shutdown the process so this is the place to close any open resources like database connections, flush buffered data to disk, etc. A callback is passed to the listener to call it when all the clean up tasks are done, call it or the process will hang up. You can also pass an error to the callback and it will be emitted back again and redirected to the error event listener. This event is fired in 2 circumstances:

  • Ctrl-c key or SIGINT signal is received. On Windows only the master process can receive a SIGINT (from a ctrl-c). If the master receives a ctrl-c/SIGINT and it uses workers, they will receive a shutdown event so they will be automatically finished.
  • Grace#shutdown() is called. If it's called on the master and you use workers all of them will receive a shutdown event and will be disconnected. If you call to shutdown() directly from a worker it will be destroyed.

Is also possible to directly call to disconnect() and destroy() in a worker. If you call to disconnect the shutdown event will be fired and if you call to destroy() it will be directly killed without firing a shutdown event and the "graceful application" will be informed about this in order to correctly manage the remaining workers.

start
Emitted right after the start() function is called.