Skip to content

Commit

Permalink
feat(launcher): send SIGKILL if SIGINT does not kill the browser
Browse files Browse the repository at this point in the history
In some cases chrome on linux does not die when it receives a SIGINT
signal. So after a SIGINT is sent, wait 2 more seconds and issue
a SIGKILL if the process is still running.
  • Loading branch information
lzatorski authored and vojtajina committed Nov 22, 2013
1 parent e4a9d5a commit eefcf00
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
34 changes: 26 additions & 8 deletions lib/launchers/Base.js
Expand Up @@ -16,14 +16,14 @@ var BEING_TIMEOUTED = 5;
var BaseBrowser = function(id, emitter, captureTimeout, retryLimit) {
var self = this;
var capturingUrl;
var exitCallback = function() {};
var exitCallbacks = [];

this.killTimeout = 2000;
this.id = id;
this.state = null;
this._tempDir = path.normalize((env.TMPDIR || env.TMP || env.TEMP || '/tmp') + '/karma-' +
id.toString());


this.start = function(url) {
capturingUrl = url;
self.state = BEING_CAPTURED;
Expand Down Expand Up @@ -59,19 +59,32 @@ var BaseBrowser = function(id, emitter, captureTimeout, retryLimit) {


this.kill = function(callback) {
exitCallback = callback || function() {};
var exitCallback = callback || function() {};

log.debug('Killing %s', self.name);

if (self.state !== FINISHED) {
if (self.state === FINISHED) {
process.nextTick(exitCallback);
} else if (self.state === BEING_KILLED) {
exitCallbacks.push(exitCallback);
} else {
self.state = BEING_KILLED;
self._process.kill();
} else {
process.nextTick(exitCallback);
exitCallbacks.push(exitCallback);
setTimeout(self._onKillTimeout, self.killTimeout);
}
};


this._onKillTimeout = function() {
if (self.state !== BEING_KILLED) {
return;
}

log.warn('%s was not killed in %d ms, sending SIGKILL.', self.name, self.killTimeout);

self._process.kill('SIGKILL');
};

this._onTimeout = function() {
if (self.state !== BEING_CAPTURED) {
return;
Expand Down Expand Up @@ -169,7 +182,12 @@ var BaseBrowser = function(id, emitter, captureTimeout, retryLimit) {
}

self.state = FINISHED;
self._cleanUpTmp(exitCallback);
self._cleanUpTmp(function(err) {
exitCallbacks.forEach(function(exitCallback) {
exitCallback(err);
});
exitCallbacks = [];
});
};


Expand Down
3 changes: 1 addition & 2 deletions test/unit/launchers/Base.spec.coffee
Expand Up @@ -156,8 +156,7 @@ describe 'launchers Base', ->
expect(killSpy).not.to.have.been.called

mockSpawn._processes[0].emit 'close', 0
expect(mockRimraf).to.have.been.calledWith path.normalize('/tmp/karma-12345'), killSpy

expect(mockRimraf).to.have.been.calledWith path.normalize('/tmp/karma-12345')
mockRimraf._callbacks[0]() # rm tempdir
expect(killSpy).to.have.been.called

Expand Down

0 comments on commit eefcf00

Please sign in to comment.