commit
562fa84344
|
@ -9,6 +9,7 @@ var $ = bitcore.util.preconditions;
|
||||||
var log = index.log;
|
var log = index.log;
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
var shuttingDown = false;
|
||||||
|
|
||||||
log.debug = function() {};
|
log.debug = function() {};
|
||||||
|
|
||||||
|
@ -138,30 +139,41 @@ function cleanShutdown(_process, node) {
|
||||||
* @param {Node} node
|
* @param {Node} node
|
||||||
*/
|
*/
|
||||||
function registerExitHandlers(_process, node) {
|
function registerExitHandlers(_process, node) {
|
||||||
|
|
||||||
function exitHandler(options, err) {
|
|
||||||
if (err) {
|
|
||||||
log.error('uncaught exception:', err);
|
|
||||||
if(err.stack) {
|
|
||||||
log.error(err.stack);
|
|
||||||
}
|
|
||||||
node.stop(function(err) {
|
|
||||||
if(err) {
|
|
||||||
log.error('Failed to stop services: ' + err);
|
|
||||||
}
|
|
||||||
_process.exit(-1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.sigint) {
|
|
||||||
cleanShutdown(_process, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//catches uncaught exceptions
|
//catches uncaught exceptions
|
||||||
_process.on('uncaughtException', exitHandler.bind(null, {exit:true}));
|
_process.on('uncaughtException', exitHandler.bind(null, {exit:true}, _process, node));
|
||||||
|
|
||||||
//catches ctrl+c event
|
//catches ctrl+c event
|
||||||
_process.on('SIGINT', exitHandler.bind(null, {sigint:true}));
|
_process.on('SIGINT', exitHandler.bind(null, {sigint:true}, _process, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will handle all the shutdown tasks that need to take place to ensure a safe exit
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {String} options.sigint - The signal given was a SIGINT
|
||||||
|
* @param {Array} options.exit - The signal given was an uncaughtException
|
||||||
|
* @param {Object} _process - The Node.js process
|
||||||
|
* @param {Node} node
|
||||||
|
* @param {Error} error
|
||||||
|
*/
|
||||||
|
function exitHandler(options, _process, node, err) {
|
||||||
|
if (err) {
|
||||||
|
log.error('uncaught exception:', err);
|
||||||
|
if(err.stack) {
|
||||||
|
log.error(err.stack);
|
||||||
|
}
|
||||||
|
node.stop(function(err) {
|
||||||
|
if(err) {
|
||||||
|
log.error('Failed to stop services: ' + err);
|
||||||
|
}
|
||||||
|
_process.exit(-1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.sigint) {
|
||||||
|
if (!shuttingDown) {
|
||||||
|
shuttingDown = true;
|
||||||
|
start.cleanShutdown(_process, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,6 +266,7 @@ function spawnChildProcess(datadir, _process) {
|
||||||
|
|
||||||
module.exports = start;
|
module.exports = start;
|
||||||
module.exports.registerExitHandlers = registerExitHandlers;
|
module.exports.registerExitHandlers = registerExitHandlers;
|
||||||
|
module.exports.exitHandler = exitHandler;
|
||||||
module.exports.registerSyncHandlers = registerSyncHandlers;
|
module.exports.registerSyncHandlers = registerSyncHandlers;
|
||||||
module.exports.setupServices = setupServices;
|
module.exports.setupServices = setupServices;
|
||||||
module.exports.spawnChildProcess = spawnChildProcess;
|
module.exports.spawnChildProcess = spawnChildProcess;
|
||||||
|
|
|
@ -304,12 +304,74 @@ describe('#start', function() {
|
||||||
});
|
});
|
||||||
it('call spawnChildProcess if there is a config option to do so', function() {
|
it('call spawnChildProcess if there is a config option to do so', function() {
|
||||||
start(options);
|
start(options);
|
||||||
|
registerSync.callCount.should.equal(1);
|
||||||
|
registerExit.callCount.should.equal(1);
|
||||||
spawn.callCount.should.equal(1);
|
spawn.callCount.should.equal(1);
|
||||||
});
|
});
|
||||||
it('not call spawnChildProcess if there is not an option to do so', function() {
|
it('not call spawnChildProcess if there is not an option to do so', function() {
|
||||||
options.config.daemon = false;
|
options.config.daemon = false;
|
||||||
start(options);
|
start(options);
|
||||||
|
registerSync.callCount.should.equal(1);
|
||||||
|
registerExit.callCount.should.equal(1);
|
||||||
spawn.callCount.should.equal(0);
|
spawn.callCount.should.equal(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('#registerExitHandlers', function() {
|
||||||
|
var stub;
|
||||||
|
var registerExitHandlers = require('../../lib/scaffold/start').registerExitHandlers;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
stub = sinon.stub(process, 'on');
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
stub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should setup two listeners on process when registering exit handlers', function() {
|
||||||
|
registerExitHandlers(process, {});
|
||||||
|
stub.callCount.should.equal(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#exitHandler', function() {
|
||||||
|
var sandbox;
|
||||||
|
var cleanShutdown;
|
||||||
|
var exitHandler;
|
||||||
|
var logStub;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
sandbox = sinon.sandbox.create();
|
||||||
|
var start = require('../../lib/scaffold/start');
|
||||||
|
var log = require('../../lib').log;
|
||||||
|
logStub = sandbox.stub(log, 'error');
|
||||||
|
cleanShutdown = sandbox.stub(start, 'cleanShutdown', function() {});
|
||||||
|
exitHandler = require('../../lib/scaffold/start').exitHandler;
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should replace the listener for SIGINT after the first SIGINT is handled', function() {
|
||||||
|
var options = { sigint: true };
|
||||||
|
var node = {};
|
||||||
|
exitHandler(options, process, node);
|
||||||
|
cleanShutdown.callCount.should.equal(1);
|
||||||
|
exitHandler(options, process, node);
|
||||||
|
cleanShutdown.callCount.should.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log all errors and stops the services nonetheless', function() {
|
||||||
|
var options = { sigint: true };
|
||||||
|
var stop = sinon.stub();
|
||||||
|
var node = {
|
||||||
|
stop: stop
|
||||||
|
};
|
||||||
|
exitHandler(options, process, node, new Error('some error'));
|
||||||
|
logStub.callCount.should.equal(2);
|
||||||
|
stop.callCount.should.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue