Skip to content

Commit

Permalink
feat(utils/exec): kills dangling child processes on main process exit
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Apr 23, 2019
1 parent 7ab4c1d commit f955538
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
33 changes: 27 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
"@types/js-yaml": "^3.12.1",
"@types/lodash.mergewith": "^4.6.6",
"@types/object-hash": "^1.2.0",
"@types/signal-exit": "^3.0.0",
"@types/uuid": "^3.4.4",
"@typescript-eslint/eslint-plugin": "^1.6.0",
"@typescript-eslint/parser": "^1.6.0",
"@zerollup/ts-transform-paths": "^1.7.1",
Expand Down Expand Up @@ -124,9 +126,11 @@
"manage-path": "^2.0.0",
"object-hash": "^1.3.1",
"promist": "^0.5.3",
"signal-exit": "^3.0.2",
"slimconf": "^0.9.0",
"spawn-command": "0.0.2-1",
"string-argv": "^0.3.0"
"string-argv": "^0.3.0",
"uuid": "^3.3.2"
},
"husky": {
"hooks": {
Expand Down
18 changes: 16 additions & 2 deletions src/utils/exec/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import sc from 'spawn-command';
import { SpawnOptions } from 'child_process';
import { SpawnOptions, ChildProcess } from 'child_process';
import { DEFAULT_STDIO } from '~/constants';
import logger from '~/utils/logger';
import { rejects } from 'errorish';
import getEnv from './get-env';
import onExit from 'signal-exit';
import uuid from 'uuid/v4';
import { IOfType } from '~/types';

export const processes: IOfType<ChildProcess> = {};

// Kill all dangling child processes on main process exit
onExit(() => Object.values(processes).forEach((p) => p.kill()));

export default async function exec(
command: string,
Expand All @@ -15,12 +23,18 @@ export default async function exec(
if (!opts.env) opts.env = await getEnv();

logger.debug('Executing: ' + command);
const id = uuid();
const ps = sc(command, opts);
processes[id] = ps;

return new Promise((resolve: (arg: void) => void, reject) => {
ps.on('close', (code: number) => {
delete processes[id];
return code ? reject(Error(`Failed: ${command}`)) : resolve();
});
ps.on('error', (err: any) => reject(err));
ps.on('error', (err: any) => {
delete processes[id];
return reject(err);
});
}).catch(rejects);
}

0 comments on commit f955538

Please sign in to comment.