Skip to content

Commit

Permalink
feat(runner): kill others will use ps-tree to kill all child processes
Browse files Browse the repository at this point in the history
  • Loading branch information
ArcherGu committed Dec 23, 2024
1 parent e7f1482 commit 75c7ac9
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@
"concurrently": "^9.1.0",
"esbuild": "^0.24.0",
"joycon": "^3.1.1",
"ps-tree": "^1.2.0",
"resolve-from": "^5.0.0"
},
"devDependencies": {
"@types/ps-tree": "^1.1.6",
"electron-builder": "25.1.8"
}
}
13 changes: 8 additions & 5 deletions packages/runner/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { build as esbuildBuild } from 'esbuild'
import { resolveConfig } from './config'
import { TAG } from './constants'
import { createLogger } from './log'
import { generateCommandToOneLine, getCachePath } from './utils'
import { generateCommandToOneLine, getCachePath, treeKill } from './utils'

interface BeforeRunHooks {
functions: ({ rIndex: number, fn: () => boolean | Promise<boolean>, result?: boolean })[]
Expand Down Expand Up @@ -271,8 +271,11 @@ export async function run(command: string, inlineConfig: InlineConfig = {}) {
cmd.close.subscribe(() => {
logger.info(TAG, `Command "${yellow(item.rId)}" exited, killing others`)
commands.forEach((c) => {
if (c.index !== item.rIndex)
c.kill('SIGKILL')
if (c.index !== item.rIndex) {
treeKill(c.pid!, 'SIGINT').catch((e) => {
logger.error(TAG, e)
})
}
})
})
}
Expand All @@ -292,12 +295,12 @@ export async function run(command: string, inlineConfig: InlineConfig = {}) {

logger.success(TAG, 'All commands finished successfully')
logger.info(TAG, 'Exiting...')
process.exit(0)
process.exit()
}, (reason) => {
const noError = reason.some((e: any) => e.exitCode === 0)
logger.warn(TAG, 'Some commands exit')
logger.info(TAG, 'Exiting...')
process.exit(noError ? 0 : 1)
process.exit(noError ? undefined : 1)
}).catch((e) => {
logger.error(TAG, e)
logger.info(TAG, 'Exiting...')
Expand Down
27 changes: 27 additions & 0 deletions packages/runner/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { PS } from 'ps-tree'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import psTree from 'ps-tree'

export const isWindows = os.platform() === 'win32'

Expand All @@ -24,3 +26,28 @@ export function getCachePath(): string {
? path.join(rootPath, 'node_modules/.doubleshot-runner')
: path.join(rootPath, '.doubleshot-runner')
}

export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}

export function psTreeSync(pid: number): Promise<readonly PS[]> {
return new Promise((resolve, reject) => {
psTree(pid, (err, children) => {
if (err) {
reject(err)
}
else {
resolve(children)
}
})
})
}

export async function treeKill(pid: number, signal?: string | number) {
const children = (await psTreeSync(pid)).filter(child => child.PID !== `${pid}` && child.PPID === `${pid}`)
for (const child of children) {
await treeKill(Number(child.PID), signal)
}
process.kill(pid, signal)
}
87 changes: 87 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit 75c7ac9

Please sign in to comment.