From 30dac3a94b87672953cae4ebb5d0bdff869db912 Mon Sep 17 00:00:00 2001 From: Rafa Mel Date: Tue, 7 May 2019 11:43:20 +0200 Subject: [PATCH] fix(utils/terminate-children): replaces ps-manager w/ terminate-children; actually sents kill signal --- src/bin/attach.ts | 11 ++++------ src/utils/ps-manager.ts | 36 --------------------------------- src/utils/terminate-children.ts | 35 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 43 deletions(-) delete mode 100644 src/utils/ps-manager.ts create mode 100644 src/utils/terminate-children.ts diff --git a/src/bin/attach.ts b/src/bin/attach.ts index 16fd10f..ff38532 100644 --- a/src/bin/attach.ts +++ b/src/bin/attach.ts @@ -1,6 +1,6 @@ import core from '~/core'; import { attach as _attach, options, resolver, add } from 'exits'; -import PSManager from '~/utils/ps-manager'; +import terminate from '~/utils/terminate-children'; import logger from '~/utils/logger'; import { wait, status } from 'promist'; @@ -18,7 +18,7 @@ export default function attach(): void { logger.debug('Received a termination signal: exiting with code 1'); return resolver('exit', 1); } - logger.debug(`${type} event: `, arg); + logger.debug(`${type} event:`, arg); return resolver(type, arg); } catch (err) { return resolver('exit', 1); @@ -26,14 +26,11 @@ export default function attach(): void { } }); add(async () => { - const manager = new PSManager(process.pid); - if (!(await manager.hasChildren())) return; - - const term = status(manager.killAll('SIGTERM', 150)); + const term = status(terminate(process.pid, 'SIGTERM', 150)); await Promise.race([term, wait(3000)]); if (term.status !== 'pending') return; - const kill = status(manager.killAll('SIGKILL', 150)); + const kill = status(terminate(process.pid, 'SIGKILL', 150)); await Promise.race([kill, wait(2000)]); if (kill.status !== 'pending') return; diff --git a/src/utils/ps-manager.ts b/src/utils/ps-manager.ts deleted file mode 100644 index df5111c..0000000 --- a/src/utils/ps-manager.ts +++ /dev/null @@ -1,36 +0,0 @@ -import tree from 'ps-tree'; -import { waitUntil, lazy } from 'promist'; -import logger from './logger'; - -export default class PSManager { - private children: Promise; - public constructor(pid: number) { - this.children = lazy((resolve, reject) => { - return tree(pid, (err, children) => - err - ? reject(err) - : resolve(children.map((child) => parseInt(child.PID))) - ); - }); - } - public async hasChildren(): Promise { - return this.children.then((children) => !!children.length); - } - public async killAll(signal: string, interval?: number): Promise { - const children = await this.children; - logger.debug( - `Seding ${signal} to all children processes: ${children.length}` - ); - - return waitUntil(() => { - for (let pid of children) { - try { - process.kill(pid, 0); - // if it doesn't error out, it's still pending - return false; - } catch (_) {} - } - return true; - }, interval); - } -} diff --git a/src/utils/terminate-children.ts b/src/utils/terminate-children.ts new file mode 100644 index 0000000..da0f99b --- /dev/null +++ b/src/utils/terminate-children.ts @@ -0,0 +1,35 @@ +import tree from 'ps-tree'; +import { waitUntil } from 'promist'; +import logger from './logger'; + +export default async function terminateChildren( + pid: number, + signal: string, + interval?: number +): Promise { + const children: number[] = await new Promise((resolve, reject) => { + return tree(pid, (err, children) => + err ? reject(err) : resolve(children.map((child) => parseInt(child.PID))) + ); + }); + + logger.debug( + `Sending ${signal} to all children processes (${children.length})` + ); + for (let pid of children) { + try { + process.kill(pid, signal); + } catch (_) {} + } + + return waitUntil(() => { + for (let pid of children) { + try { + process.kill(pid, 0); + // if it doesn't error out, it's still pending + return false; + } catch (_) {} + } + return true; + }, interval); +}