diff --git a/packages/xarc-app-dev/lib/dev-admin/admin-server.js b/packages/xarc-app-dev/lib/dev-admin/admin-server.js index 5e0e52b0b..45145bc8c 100644 --- a/packages/xarc-app-dev/lib/dev-admin/admin-server.js +++ b/packages/xarc-app-dev/lib/dev-admin/admin-server.js @@ -14,7 +14,10 @@ const WebpackDevRelay = require("./webpack-dev-relay"); const { displayLogs } = require("./log-reader"); const { fork } = require("child_process"); const ConsoleIO = require("./console-io"); -const logger = require("@xarc/app/lib/logger"); +const winstonLogger = require("@xarc/app/lib/winston-logger"); +const winston = require("winston"); +const logger = winstonLogger(winston, false); +const { doCleanup } = require("./cleanup"); const xaa = require("xaa"); const { formUrl } = require("../utils"); const { @@ -91,11 +94,6 @@ class AdminServer { // await this.startProxyServer("--inspect-brk"); await this.startProxyServer(); } - - this._shutdown || - setTimeout(() => { - this.showMenu(true); - }, 100); } logTime(msg) { @@ -214,6 +212,9 @@ ${proxyItem}M - Show this menu Q - Shutdown this.kill(APP_SERVER_NAME, "SIGINT"), this.kill(PROXY_SERVER_NAME, "SIGINT") ]); + + this._io.shutdown(); + await doCleanup(); this._io.exit(); } @@ -545,6 +546,11 @@ ${instruction}` checkLine: str => { if (!this._fullyStarted && str.includes("server running")) { this._fullyStarted = true; + // opens menu automatically once after startup + this._shutdown || + setTimeout(() => { + this.showMenu(true); + }, 5000); this.logTime(`App is ready in dev mode, total time took`); } return str; diff --git a/packages/xarc-app-dev/lib/dev-admin/cleanup.js b/packages/xarc-app-dev/lib/dev-admin/cleanup.js new file mode 100644 index 000000000..bed844ca0 --- /dev/null +++ b/packages/xarc-app-dev/lib/dev-admin/cleanup.js @@ -0,0 +1,47 @@ +"use strict"; + +/* eslint-disable no-console, no-process-exit */ +const { psChildren } = require("ps-get"); + +/** + * Attempt to clean up any child process remaining + */ +let cleaned = false; + +const doCleanup = async () => { + if (cleaned) { + return; + } + cleaned = true; + const children = await psChildren(process.pid); + children.reverse().forEach(c => { + try { + console.log( + "detected child process left from dev-admin, PID:", + c.pid, + "- trying to terminate it" + ); + process.kill(c.pid, "SIGINT"); + } catch { + // + } + }); +}; + +["uncaughtException", "unhandledRejection"].forEach(event => { + process.on(event, async err => { + console.log("dev-admin failure", event, err.stack); + await doCleanup(); + process.exit(process.exitCode); + }); +}); + +["SIGTERM", "SIGINT", "SIGHUP"].forEach(sig => { + process.on(sig, async name => { + console.log("dev-admin received signal:", name); + await doCleanup(); + process.exit(process.exitCode); + }); +}); + +module.exports = { doCleanup }; diff --git a/packages/xarc-app-dev/lib/dev-admin/index.js b/packages/xarc-app-dev/lib/dev-admin/index.js index 24209eef0..ae7eb9837 100644 --- a/packages/xarc-app-dev/lib/dev-admin/index.js +++ b/packages/xarc-app-dev/lib/dev-admin/index.js @@ -20,4 +20,6 @@ const AdminServer = require("./admin-server"); const admin = new AdminServer(parsed); +require("./cleanup"); + admin.start(); diff --git a/packages/xarc-app-dev/package.json b/packages/xarc-app-dev/package.json index 077944cb6..45cba913f 100644 --- a/packages/xarc-app-dev/package.json +++ b/packages/xarc-app-dev/package.json @@ -72,7 +72,7 @@ "nyc": "^14.1.1", "optional-require": "^1.0.0", "prompts": "^2.2.1", - "ps-get": "^1.0.1", + "ps-get": "^1.1.0", "regenerator-runtime": "^0.13.2", "request": "^2.88.0", "require-at": "^1.0.2", diff --git a/packages/xarc-app/lib/winston-logger.js b/packages/xarc-app/lib/winston-logger.js index 835422d2e..5620e5f05 100644 --- a/packages/xarc-app/lib/winston-logger.js +++ b/packages/xarc-app/lib/winston-logger.js @@ -2,9 +2,9 @@ /* eslint-disable no-magic-numbers */ -const makeWinstonLogger = winston => { +const makeWinstonLogger = (winston, handlers = true) => { return new winston.Logger({ - exceptionHandlers: [ + exceptionHandlers: handlers && [ new winston.transports.Console({ colorize: true, prettyPrint: true