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 3751873 commit c0fa49a
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 c0fa49a

Please sign in to comment.