Fixed the daemon process termination.

From now on, we spawn a detached process that
will periodically check whether the parent Theia
the process is alive, if no, terminates the daemon.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
Akos Kitta 2019-07-25 12:01:23 +02:00
parent 83e966d208
commit d29ed24e49
5 changed files with 112 additions and 17 deletions

View File

@ -8,6 +8,7 @@
},
"dependencies": {
"@grpc/grpc-js": "^0.4.0",
"@theia/application-package": "next",
"@theia/core": "next",
"@theia/editor": "next",
"@theia/filesystem": "next",
@ -18,9 +19,12 @@
"@theia/workspace": "next",
"@theia/navigator": "next",
"@theia/terminal": "next",
"@types/ps-tree": "^1.1.0",
"@types/which": "^1.3.1",
"css-element-queries": "^1.2.0",
"p-queue": "^5.0.0",
"ps-tree": "^1.2.0",
"tree-kill": "^1.2.1",
"which": "^1.3.1"
},
"scripts": {

View File

@ -1,12 +1,12 @@
import * as which from 'which';
import * as os from 'os';
import { join, delimiter } from 'path';
import { exec } from 'child_process';
import { ChildProcess } from 'child_process';
import { exec, spawn, SpawnOptions } from 'child_process';
import { inject, injectable, named } from 'inversify';
import { ILogger } from '@theia/core/lib/common/logger';
import { BackendApplicationContribution } from '@theia/core/lib/node';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { environment } from '@theia/application-package/lib/environment';
import { DaemonLog } from './daemon-log';
import { ToolOutputServiceServer } from '../common/protocol/tool-output-service';
@ -23,8 +23,6 @@ export class ArduinoDaemon implements BackendApplicationContribution {
@inject(ToolOutputServiceServer)
protected readonly toolOutputService: ToolOutputServiceServer;
protected process: ChildProcess | undefined;
protected isReady = new Deferred<boolean>();
async onStart() {
@ -48,6 +46,15 @@ export class ArduinoDaemon implements BackendApplicationContribution {
}
console.log(stdout);
});
const options: SpawnOptions = {
env: environment.electron.runAsNodeEnv(),
detached: true,
stdio: 'ignore'
}
const command = process.execPath;
const cp = spawn(command, [join(__dirname, 'daemon-watcher.js'), String(process.pid), String(daemon.pid)], options);
cp.unref();
if (daemon.stdout) {
daemon.stdout.on('data', data => {
this.toolOutputService.publishNewOutput('daemon', data.toString());
@ -63,7 +70,6 @@ export class ArduinoDaemon implements BackendApplicationContribution {
if (daemon.stderr) {
daemon.on('exit', (code, signal) => DaemonLog.log(this.logger, `Daemon exited with code: ${code}. Signal was: ${signal}.`));
}
this.process = daemon;
}
await new Promise(resolve => setTimeout(resolve, 2000));
@ -78,13 +84,4 @@ export class ArduinoDaemon implements BackendApplicationContribution {
}
}
onStop() {
if (!this.process) {
return;
}
DaemonLog.log(this.logger, `Shutting down daemon.`);
this.process.kill("SIGTERM");
}
}

View File

@ -55,7 +55,7 @@ export class BoardsServiceImpl implements BoardsService {
}
}
}
resolve({boards});
resolve({ boards });
})
});
}

View File

@ -0,0 +1,17 @@
import * as psTree from 'ps-tree';
const kill = require('tree-kill');
const [theiaPid, daemonPid] = process.argv.slice(2).map(id => Number.parseInt(id, 10));
setInterval(() => {
try {
// Throws an exception if the Theia process doesn't exist anymore.
process.kill(theiaPid, 0);
} catch {
psTree(daemonPid, function (_, children) {
for (const { PID } of children) {
kill(PID);
}
kill(daemonPid, () => process.exit());
});
}
}, 1000);

View File

@ -1015,6 +1015,22 @@
semver "^5.4.1"
write-json-file "^2.2.0"
"@theia/application-package@next":
version "0.9.0-next.7a419b76"
resolved "https://registry.yarnpkg.com/@theia/application-package/-/application-package-0.9.0-next.7a419b76.tgz#9061d364a9e03218285c04477ca4b8ca3cfcca89"
integrity sha512-MoYXQiFSAjSvMClGz6GSSWwKe6cnLp9mprDBQRGfVXkVeQIc2nB6reKlRMpnp+UCo9jmQwyZbvUxsiMWO5wo6A==
dependencies:
"@types/fs-extra" "^4.0.2"
"@types/request" "^2.0.3"
"@types/semver" "^5.4.0"
"@types/write-json-file" "^2.2.1"
changes-stream "^2.2.0"
fs-extra "^4.0.2"
is-electron "^2.1.0"
request "^2.82.0"
semver "^5.4.1"
write-json-file "^2.2.0"
"@theia/cli@next":
version "0.9.0-next.3587c237"
resolved "https://registry.yarnpkg.com/@theia/cli/-/cli-0.9.0-next.3587c237.tgz#0cd61bc15ce8fe8bfbc9bb40fa305c444799489f"
@ -1414,6 +1430,11 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==
"@types/ps-tree@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@types/ps-tree/-/ps-tree-1.1.0.tgz#7e2034e8ccdc16f6b0ced7a88529ebcb3b1dc424"
integrity sha512-rm5GU5sefQpg2d/DQ+fMDZnl9aPiJjJ9FYA12isIocNTZqu9VDZRgCRBx3oYFEdmDpmPmY4hxxmY/+1a84Rtzg==
"@types/range-parser@*":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
@ -4665,7 +4686,7 @@ duplexer3@^0.1.4:
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
duplexer@^0.1.1:
duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=
@ -4964,6 +4985,19 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
event-stream@=3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=
dependencies:
duplexer "~0.1.1"
from "~0"
map-stream "~0.1.0"
pause-stream "0.0.11"
split "0.3"
stream-combiner "~0.0.4"
through "~2.3.1"
eventemitter3@^3.1.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
@ -5541,6 +5575,11 @@ from2@^2.1.0, from2@^2.1.1:
inherits "^2.0.1"
readable-stream "^2.0.0"
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
@ -7626,6 +7665,11 @@ map-obj@^2.0.0:
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9"
integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk=
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=
map-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
@ -8913,6 +8957,13 @@ path-type@^3.0.0:
dependencies:
pify "^3.0.0"
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=
dependencies:
through "~2.3"
pbkdf2@^3.0.3:
version "3.0.17"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
@ -9414,6 +9465,13 @@ prr@~1.0.1:
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
ps-tree@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd"
integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==
dependencies:
event-stream "=3.3.4"
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@ -10584,6 +10642,13 @@ split2@^2.0.0:
dependencies:
through2 "^2.0.2"
split@0.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=
dependencies:
through "2"
split@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
@ -10646,6 +10711,13 @@ stream-browserify@^2.0.1:
inherits "~2.0.1"
readable-stream "^2.0.2"
stream-combiner@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=
dependencies:
duplexer "~0.1.1"
stream-each@^1.1.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
@ -11045,7 +11117,7 @@ through2@~0.2.3:
readable-stream "~1.1.9"
xtend "~2.1.1"
through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8:
through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
@ -11166,6 +11238,11 @@ trash@^4.0.1:
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
tree-kill@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a"
integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"