UNPKG

5.26 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10var __importDefault = (this && this.__importDefault) || function (mod) {
11 return (mod && mod.__esModule) ? mod : { "default": mod };
12};
13var __importStar = (this && this.__importStar) || function (mod) {
14 if (mod && mod.__esModule) return mod;
15 var result = {};
16 if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
17 result["default"] = mod;
18 return result;
19};
20Object.defineProperty(exports, "__esModule", { value: true });
21const chalk_1 = __importDefault(require("chalk"));
22const child_process_1 = require("child_process");
23const pstree_remy_1 = __importStar(require("pstree.remy"));
24const platform_1 = require("../util/platform");
25function invariant(condition, message) {
26 if (!condition) {
27 const err = new Error(message);
28 err.name = 'Invariant Violation';
29 throw err;
30 }
31}
32class AppController {
33 constructor(executablePath, argv) {
34 this.state = {
35 appRunning: false,
36 proc: null,
37 pid: null,
38 };
39 this.executablePath = executablePath;
40 this.argv = argv;
41 }
42 stopApp() {
43 return __awaiter(this, void 0, void 0, function* () {
44 return new Promise(resolve => {
45 if (this.state.appRunning) {
46 console.log('Sending SIGTERM signal to app...');
47 const { pid } = this.state;
48 const closeHandler = (code, signal) => {
49 this.setState({
50 appRunning: false,
51 proc: null,
52 pid: null,
53 });
54 resolve();
55 };
56 if (platform_1.isWindows()) {
57 child_process_1.exec('taskkill /pid ' + pid + ' /T /F').on('close', closeHandler);
58 }
59 else {
60 // pstree is used to kill the full subtree of a spawned app
61 pstree_remy_1.default(pid, (_, children) => {
62 if (pstree_remy_1.hasPS) {
63 // we now send SIGTERM to the spawned process
64 child_process_1.spawn('kill', ['-s', 'SIGTERM', pid].concat(children)).on('close', closeHandler);
65 }
66 else {
67 const pids = children.concat(pid).sort();
68 pids.forEach(childPid => {
69 // 15 is for SIGTERM
70 child_process_1.exec('kill -15 ' + childPid).on('close', closeHandler);
71 });
72 }
73 });
74 }
75 }
76 else {
77 resolve();
78 }
79 });
80 });
81 }
82 runApp() {
83 invariant(!this.state.appRunning, "Can't start app when app is already running!");
84 // spawn the process
85 const proc = child_process_1.spawn('node', [this.executablePath, ...this.argv]);
86 // attach event listeners
87 proc.on('error', e => {
88 console.log(chalk_1.default.red('Failed to start app: ' + e.message));
89 this.setState({
90 appRunning: false,
91 proc: null,
92 pid: null,
93 });
94 });
95 proc.on('exit', (code, signal) => {
96 if (code !== null) {
97 console.log(code > 0
98 ? chalk_1.default.red('App exited with code ' + code + '.')
99 : chalk_1.default.green('App exited with code ' + code + '.'));
100 }
101 if (signal !== null) {
102 console.log(signal !== 'SIGTERM'
103 ? chalk_1.default.red('App killed with signal ' + signal + '.')
104 : chalk_1.default.green('App killed with signal SIGTERM.'));
105 }
106 this.setState({
107 appRunning: false,
108 proc: null,
109 pid: null,
110 });
111 });
112 // pipe spawned output stream to current process's output streams
113 proc.stdout.pipe(process.stdout);
114 proc.stderr.pipe(process.stderr);
115 console.log(chalk_1.default.green('App started!'));
116 this.setState({
117 proc,
118 pid: proc.pid.toString(),
119 appRunning: true,
120 });
121 }
122 setState(state) {
123 this.state = state;
124 }
125}
126exports.AppController = AppController;
127//# sourceMappingURL=processHandler.js.map
\No newline at end of file