Skip to content

Commit

Permalink
emit a fatal event instead of exit the process
Browse files Browse the repository at this point in the history
also try to close the dependency which might started to do some work, like the rulecache
  • Loading branch information
timaschew committed Jul 5, 2016
1 parent a8ae85f commit 53dffe7
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 24 deletions.
9 changes: 6 additions & 3 deletions bin/deepstream-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ function action() {
// ensure there is no pid file with a running process
pidHelper.ensureNotRunning( function( err ) {
if ( err ) {
return pidHelper.exit( err );
return pidHelper.exit( err, true );
}
const child = child_process.spawn( path.resolve( __dirname, 'deepstream' ), ['start'].concat( args ), {
detached: true,
stdio: [ 'ignore']
} );
const WAIT_FOR_ERRORS = 2000;
const WAIT_FOR_ERRORS = 3000;
// register handler if the child process will fail within WAIT_FOR_ERRORS period
child.on( 'close', detachErrorHandler );
child.on( 'exit', detachErrorHandler );
Expand All @@ -78,6 +78,9 @@ function action() {
ds.on( 'started', function() {
pidHelper.save( process.pid );
} );
ds.on( 'fatal', function() {
pidHelper.exit(new Error( 'Shutting down deepstream due to a fatal error' ));
} );
ds.start();
} catch ( err ) {
console.error( err.toString() );
Expand All @@ -91,7 +94,7 @@ function action() {
}

function detachErrorHandler() {
console.error( 'Error during detaching the deepstream process, run without --detach'.red );
console.error( 'Error during detaching the deepstream process, see logs or run without --detach'.red );
process.exit( 1 );
}

Expand Down
13 changes: 8 additions & 5 deletions bin/pid-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,17 @@ const ensureNotRunning = function( callback ) {
* @param {Error} err Optional error object
* @return {void}
*/
const exit = function( err ) {
if ( err instanceof Error ) {
const exit = function( err, keepPid ) {
const errorCode = err ? 1 : 0
if( err instanceof Error ) {
console.error ( colors.red( err.toString() ) );
process.exit( 1 );
} else {
}
if( !keepPid ) {
remove( function() {
process.exit( 0 );
process.exit( errorCode );
} );
} else {
process.exit( errorCode );
}
};

Expand Down
21 changes: 21 additions & 0 deletions src/deepstream.io.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,12 @@ Deepstream.prototype._start = function() {
var i,
initialiser;

this.initialisers = []
for( i = 0; i < this._plugins.length; i++ ) {
initialiser = new DependencyInitialiser( this._options, this._plugins[ i ] );
this.initialisers.push(initialiser)
initialiser.once( 'ready', this._checkReady.bind( this, this._plugins[ i ], initialiser.getDependency() ) );
initialiser.once( 'fatal', this._onFatal.bind(this) );
}
this._checkReady( 'logger', this._options.logger );
};
Expand Down Expand Up @@ -363,4 +366,22 @@ Deepstream.prototype._onPluginError = function( pluginName, error ) {
this._options.logger.log( C.LOG_LEVEL.ERROR, C.EVENT.PLUGIN_ERROR, msg );
};

/**
* Callback for plugin fatal errors that occur at initialization time. Errors during initialisation
* are handled by the DependencyInitialiser
*
* @private
* @returns {void}
*/
Deepstream.prototype._onFatal = function() {
for( i = 0; i < this.initialisers.length; i++ ) {
var initialiser = this.initialisers[i];
var dependency = initialiser.getDependency();
if( typeof dependency.close === 'function' ) {
dependency.close();
}
}
this.emit('fatal')
};

module.exports = Deepstream;
5 changes: 5 additions & 0 deletions src/permission/config-permission-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,9 @@ ConfigPermissionHandler.prototype._ready = function() {
}
};

ConfigPermissionHandler.prototype.close = function() {
this._ruleCache.close();
this.emit( 'close' );
};

module.exports = ConfigPermissionHandler;
16 changes: 14 additions & 2 deletions src/permission/rule-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
var RuleCache = function( options ) {
this._options = options;
this._data = {};
setInterval( this._purge.bind( this ), options.cacheEvacuationInterval );
this._intervalId = setInterval( this._purge.bind( this ), options.cacheEvacuationInterval );
};

/**
Expand Down Expand Up @@ -106,4 +106,16 @@ RuleCache.prototype._purge = function() {
}
};

module.exports = RuleCache;
/**
* Stop the interval to trigger the _purge method.
*
* @private
* @returns {void}
*/
RuleCache.prototype.close = function() {
if (this._intervalId) {
clearInterval( this._intervalId );
}
}

module.exports = RuleCache;
5 changes: 3 additions & 2 deletions src/utils/dependency-initialiser.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ DependencyInitialiser.prototype._onReady = function() {
*/
DependencyInitialiser.prototype._onTimeout = function() {
this._logError( this._name + ' wasn\'t initialised in time' );
process.exit( 1 );
this.emit( 'fatal' )
};

/**
Expand All @@ -84,8 +84,9 @@ DependencyInitialiser.prototype._onTimeout = function() {
DependencyInitialiser.prototype._onError = function( error ) {
if( this.isReady !== true ) {
this._logError( 'Error while initialising ' + this._name + ': ' + error.toString() );
process.exit( 1 );
}
this.emit( 'fatal' )

};

/**
Expand Down
19 changes: 7 additions & 12 deletions test/utils/dependency-initialiserSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ describe( 'encounters timeouts and errors during dependency initialisations', fu
var dependencyInitialiser;
var readySpy;
var onReady = jasmine.createSpy( 'onReady' );
var exit = jasmine.createSpy( 'exit');
var log = jasmine.createSpy( 'log' );
var fatal = jasmine.createSpy( 'fatal' );
var originalProcessExit = process.exit;
var originalConsoleLog = console.log;
var options = {
Expand All @@ -49,10 +49,7 @@ describe( 'encounters timeouts and errors during dependency initialisations', fu
dependencyInitialisationTimeout: 1
};

it( 'disables process exit', function(){
Object.defineProperty( process, 'exit', {
value: exit
});
it( 'disables console.error', function(){

Object.defineProperty( console, 'error', {
value: log
Expand All @@ -62,13 +59,14 @@ describe( 'encounters timeouts and errors during dependency initialisations', fu
it( 'creates a depdendency initialiser', function( next ){
dependencyInitialiser = new DependencyInitialiser( options, 'plugin' );
dependencyInitialiser.on( 'ready', onReady );
dependencyInitialiser.on( 'fatal', fatal );
expect( options.plugin.isReady ).toBe( false );
setTimeout( next, 5 );
});

it( 'doesnt initialise a plugin in time', function(){
expect( onReady ).not.toHaveBeenCalled();
expect( exit ).toHaveBeenCalled();
expect( fatal ).toHaveBeenCalled();
expect( options.logger.log ).toHaveBeenCalledWith( 3, 'PLUGIN_ERROR', 'plugin wasn\'t initialised in time' );
});

Expand All @@ -81,19 +79,16 @@ describe( 'encounters timeouts and errors during dependency initialisations', fu
});

it( 'has logged the plugin error', function(){
expect( exit ).toHaveBeenCalled();
expect( fatal ).toHaveBeenCalled();
expect( onReady ).not.toHaveBeenCalled();
expect( log ).toHaveBeenCalledWith( 'Error while initialising dependency' );
expect( log ).toHaveBeenCalledWith( 'Error while initialising plugin: something went wrong' );
});

it( 'enables process exit', function(){
Object.defineProperty( process, 'exit', {
value: originalProcessExit
});
it( 'enables console.error', function(){

Object.defineProperty( console, 'error', {
value: originalConsoleLog
});
});
});
});

0 comments on commit 53dffe7

Please sign in to comment.