Skip to content

Commit

Permalink
Handle SIGINT via async-exit-hook (closes DevExpress#1378) (DevExpres…
Browse files Browse the repository at this point in the history
…s#1576)

* Handle SIGINT via async-exit-hook (closes DevExpress#1378)

* Use updated package

* Fix typo

* Add message
  • Loading branch information
AndreyBelym authored and AlexanderMoskovkin committed Jul 20, 2017
1 parent 7f701ed commit 648836b
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 10 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"prepublish": "publish-please guard"
},
"dependencies": {
"async-exit-hook": "^1.1.2",
"babel-core": "^6.22.1",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.22.0",
Expand All @@ -78,7 +79,7 @@
"is-ci": "^1.0.10",
"is-glob": "^2.0.1",
"lodash": "^4.13.1",
"log-update": "^1.0.2",
"log-update-async-hook": "^2.0.2",
"map-reverse": "^1.0.1",
"mkdirp": "^0.5.1",
"moment": "^2.10.3",
Expand Down
5 changes: 3 additions & 2 deletions src/browser/connection/gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ export default class BrowserConnectionGateway {

static onHeartbeat (req, res, connection) {
if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) {
connection.heartbeat();
res.end();
var status = connection.heartbeat();

respondWithJSON(res, status);
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/browser/connection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { readSync as read } from 'read-file-relative';
import promisifyEvent from 'promisify-event';
import shortId from 'shortid';
import COMMAND from './command';
import STATUS from './status';
import { GeneralError } from '../../errors/runtime';
import MESSAGE from '../../errors/runtime/message';

Expand Down Expand Up @@ -36,6 +37,7 @@ export default class BrowserConnection extends EventEmitter {
this.provider = browserInfo.provider;

this.permanent = permanent;
this.closing = false;
this.closed = false;
this.ready = false;
this.opened = false;
Expand Down Expand Up @@ -164,9 +166,11 @@ export default class BrowserConnection extends EventEmitter {
}

close () {
if (this.closed)
if (this.closed || this.closing)
return;

this.closing = true;

this._closeBrowser()
.then(() => {
this.browserConnectionGateway.stopServingConnection(this);
Expand All @@ -193,6 +197,11 @@ export default class BrowserConnection extends EventEmitter {
heartbeat () {
clearTimeout(this.heartbeatTimeout);
this._waitForHeartbeat();

return {
code: this.closing ? STATUS.closing : STATUS.ok,
url: this.closing ? this.idleUrl : ''
};
}

renderIdlePage () {
Expand Down
4 changes: 4 additions & 0 deletions src/browser/connection/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
ok: 'ok',
closing: 'closing'
};
17 changes: 17 additions & 0 deletions src/cli/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import chalk from 'chalk';
import resolveCwd from 'resolve-cwd';
import setupExitHook from 'async-exit-hook';
import browserProviderPool from '../browser/provider/pool';
import { GeneralError, APIError } from '../errors/runtime';
import MESSAGE from '../errors/runtime/message';
Expand All @@ -8,6 +9,18 @@ import log from './log';
import remotesWizard from './remotes-wizard';
import createTestCafe from '../';


var showMessageOnExit = true;

function exitHandler () {
if (!showMessageOnExit)
return;

log.hideSpinner();
log.write('Stopping TestCafe...');
log.showSpinner();
}

function exit (code) {
log.hideSpinner();

Expand Down Expand Up @@ -70,6 +83,7 @@ async function runTests (argParser) {
}

finally {
showMessageOnExit = false;
await testCafe.close();
}

Expand Down Expand Up @@ -115,6 +129,8 @@ function useLocalInstallation () {
if (useLocalInstallation())
return;

setupExitHook(exitHandler);

try {
var argParser = new CliArgumentParser();

Expand All @@ -126,6 +142,7 @@ function useLocalInstallation () {
await runTests(argParser);
}
catch (err) {
showMessageOnExit = false;
error(err);
}
})();
Expand Down
2 changes: 1 addition & 1 deletion src/cli/log.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import tty from 'tty';
import elegantSpinner from 'elegant-spinner';
import logUpdate from 'log-update';
import logUpdate from 'log-update-async-hook';
import chalk from 'chalk';
import isCI from 'is-ci';

Expand Down
19 changes: 15 additions & 4 deletions src/client/browser/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// TODO: once we'll have client commons load it from there instead of node modules (currently it's leads to two copies of this packages on client)
import Promise from 'pinkie';
import COMMAND from '../../browser/connection/command';
import STATUS from '../../browser/connection/status';


const HEARTBEAT_INTERVAL = 30 * 1000;
const HEARTBEAT_INTERVAL = 2 * 1000;

var allowInitScriptExecution = false;

Expand Down Expand Up @@ -36,9 +37,19 @@ function isCurrentLocation (url) {

//API
export function startHeartbeat (heartbeatUrl, createXHR) {
sendXHR(heartbeatUrl, createXHR);

window.setInterval(() => sendXHR(heartbeatUrl, createXHR), HEARTBEAT_INTERVAL);
function heartbeat () {
sendXHR(heartbeatUrl, createXHR)
.then(status => {
if (status.code === STATUS.closing && !isCurrentLocation(status.url)) {
stopInitScriptExecution();
document.location = status.url;
}
});
}

window.setInterval(heartbeat, HEARTBEAT_INTERVAL);

heartbeat();
}

function executeInitScript (initScriptUrl, createXHR) {
Expand Down
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Promise from 'pinkie';
import TestCafe from './testcafe';
import * as endpointUtils from 'endpoint-utils';
import setupExitHook from 'async-exit-hook';
import { GeneralError } from './errors/runtime';
import MESSAGE from './errors/runtime/message';
import embeddingUtils from './embedding-utils';
Expand Down Expand Up @@ -42,7 +43,11 @@ async function createTestCafe (hostname, port1, port2) {
getValidPort(port2)
]);

return new TestCafe(hostname, port1, port2);
var testcafe = new TestCafe(hostname, port1, port2);

setupExitHook(cb => testcafe.close().then(cb));

return testcafe;
}

// Embedding utils
Expand Down
6 changes: 6 additions & 0 deletions src/testcafe.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const FAVICON = read('./client/ui/favicon.ico', true);

export default class TestCafe {
constructor (hostname, port1, port2) {
this.closed = false;
this.proxy = new Proxy(hostname, port1, port2);
this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy);
this.runners = [];
Expand Down Expand Up @@ -62,6 +63,11 @@ export default class TestCafe {
}

async close () {
if (this.closed)
return;

this.closed = true;

await Promise.all(this.runners.map(runner => runner.stop()));

await browserProviderPool.dispose();
Expand Down

0 comments on commit 648836b

Please sign in to comment.