Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice to gracefully shutdown a Node.js program from an external signal?

Tags:

node.js

What is the best-practice for gracefully exiting a Node.js program from an external signal?

I currently use this in my code:

process.on( 'SIGINT', function() {
  console.log( "\ngracefully shutting down from  SIGINT (Crtl-C)" )
  // some other closing procedures go here
  process.exit( )
})
like image 287
EhevuTov Avatar asked Feb 15 '12 18:02

EhevuTov


People also ask

What is graceful shutdown in node js?

Graceful shutdown means when all your requests to the server is respond and not any data processing work left.

What is graceful shutdown?

A graceful shutdown is when a computer is turned off by software function and the operating system (OS) is allowed to perform its tasks of safely shutting down processes and closing connections. A hard shutdown is when the computer is forcibly shut down by interruption of power.


2 Answers

It depends entirely on what your program is doing but I would say something like this:

A graceful shutdown means that any "started" I/O operations (e.g. file reads, HTTP request/responses, etc.) should complete but no new ones can be started. So your shutdown handler should prevent the possibility of starting any new operations (e.g. unbind any port listeners, prevent any new fs calls, etc.), ensure that any currently running handlers run to completion, and then exit the process.

[Edit] Of course, if your application doesn't care about the above concerns then there really isn't anything to do. When the process exits all open file/socket handles will be closed automatically so there are no problems with leaked resources.

like image 21
maerics Avatar answered Sep 22 '22 15:09

maerics


Hope this template helps. I got most of this from Simon Holmes' book Getting MEAN. Credit goes to him.

var mongoose = require( 'mongoose' );
var gracefulShutdown;
var dbURI = 'mongodb://localhost/xxx';
if (process.env.NODE_ENV === 'production') {
  dbURI = process.env.MONGOLAB_URI;
}

mongoose.connect(dbURI);

// CONNECTION EVENTS
mongoose.connection.on('connected', function () {
  console.log('Mongoose connected to ' + dbURI);
});
mongoose.connection.on('error',function (err) {
  console.log('Mongoose connection error: ' + err);
});
mongoose.connection.on('disconnected', function () {
  console.log('Mongoose disconnected');
});

// CAPTURE APP TERMINATION / RESTART EVENTS
// To be called when process is restarted or terminated
gracefulShutdown = function (msg, callback) {
  mongoose.connection.close(function () {
    console.log('Mongoose disconnected through ' + msg);
    callback();
  });
};
// For nodemon restarts
process.once('SIGUSR2', function () {
  gracefulShutdown('nodemon restart', function () {
    process.kill(process.pid, 'SIGUSR2');
  });
});
// For app termination
process.on('SIGINT', function() {
  gracefulShutdown('app termination', function () {
    process.exit(0);
  });
});
// For Heroku app termination
process.on('SIGTERM', function() {
  gracefulShutdown('Heroku app termination', function () {
    process.exit(0);
  });
});
// TODO : For Modulus app termination

// BRING IN YOUR SCHEMAS & MODELS.
require('./yyy');
like image 178
Jek Avatar answered Sep 21 '22 15:09

Jek