Use different kill method for watcher

This commit is contained in:
Chi Vinh Le
2018-07-13 02:00:23 -03:00
parent cf1c5c58c2
commit 05552f7a84
6 changed files with 56 additions and 16 deletions
+9
View File
@@ -16521,6 +16521,15 @@
"integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==",
"dev": true
},
"pstree.remy": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
"integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
"dev": true,
"requires": {
"ps-tree": "^1.1.0"
}
},
"public-encrypt": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+1
View File
@@ -126,6 +126,7 @@
"postcss-prepend-imports": "^1.0.1",
"postcss-preset-env": "^5.2.1",
"prettier": "^1.13.4",
"pstree.remy": "^1.1.0",
"query-string": "^6.1.0",
"raw-loader": "^0.5.1",
"react": "^16.4.0",
+37 -13
View File
@@ -1,6 +1,8 @@
import { ChildProcess } from "child_process";
import spawn from "cross-spawn";
import { Cancelable, debounce } from "lodash";
import psTree from "pstree.remy";
import { Executor } from "./types";
interface LongRunningExecutorOptions {
@@ -31,9 +33,6 @@ export default class LongRunningExecutor implements Executor {
this.isRunning = true;
this.process = spawn(this.cmd, this.args as string[], {
stdio: "inherit",
// Have all child processes in their own group.
// See `process.kill` below.
detached: true,
shell: !this.args,
});
@@ -51,18 +50,43 @@ export default class LongRunningExecutor implements Executor {
});
}
private restart(): void {
private async restart(): Promise<void> {
this.shouldRestart = true;
// Using the `-` will kill all child procceses in the group.
// See: https://azimi.me/2014/12/31/kill-child_process-node-js.html
process.kill(-this.process!.pid, "SIGTERM");
return this.internalKill();
}
private kill(): void {
private async kill(): Promise<void> {
this.shouldRestart = false;
// Using the `-` will kill all child procceses in the group.
// See: https://azimi.me/2014/12/31/kill-child_process-node-js.html
process.kill(-this.process!.pid, "SIGTERM");
return this.internalKill();
}
private async internalKill(): Promise<void> {
return new Promise<void>((resolve, reject) => {
const signal = "SIGTERM";
if (process.platform === "win32") {
// Force kill (/F) the whole child tree (/T) by PID
spawn.sync("taskkill", [
"/pid",
this.process!.pid.toString(),
"/T",
"/F",
]);
resolve();
return;
}
psTree(this.process!.pid, (err, kids) => {
if (err) {
reject(err);
}
spawn.sync("kill", [
`-${signal}`,
this.process!.pid.toString(),
...kids.map(p => p.PID.toString()),
]);
resolve();
});
});
}
// This is called before watching starts.
@@ -71,10 +95,10 @@ export default class LongRunningExecutor implements Executor {
}
// This is called before exiting.
public onCleanup() {
public async onCleanup() {
this.restartDebounced.cancel();
if (this.isRunning) {
this.kill();
await this.kill();
}
}
+6
View File
@@ -0,0 +1,6 @@
declare module "pstree.remy" {
export default function psTree(
pid: number,
callback: (err: Error, kids: Array<{ PID: number }>) => void
): void;
}
+1 -1
View File
@@ -13,7 +13,7 @@ export interface Watcher {
export interface Executor {
onInit?(): void;
onCleanup?(): void;
onCleanup?(): void | Promise<void>;
execute(filePath: string): void;
}
+2 -2
View File
@@ -32,10 +32,10 @@ function prependRootDir(prepend: string, cfg: WatchConfig): WatchConfig {
function setupCleanup(config: Config) {
["SIGINT", "SIGTERM"].forEach(signal =>
process.once(signal as any, () => {
process.once(signal as any, async () => {
for (const key of Object.keys(config.watchers)) {
if (config.watchers[key].executor.onCleanup) {
config.watchers[key].executor.onCleanup!();
await config.watchers[key].executor.onCleanup!();
}
}
process.exit(0);