refactor(subprocess): derive termination state
This commit is contained in:
@@ -383,7 +383,6 @@ export function spawnSubprocess(spec: SubprocessSpawnSpec, internals: SpawnInter
|
|||||||
const stderrCollector = collectStream(errMode, child.stderr, 'stderr')
|
const stderrCollector = collectStream(errMode, child.stderr, 'stderr')
|
||||||
|
|
||||||
let graceTimer: ReturnType<typeof scheduleFiniteTimeout> | undefined
|
let graceTimer: ReturnType<typeof scheduleFiniteTimeout> | undefined
|
||||||
let terminationStarted = false
|
|
||||||
let treeExitObserved = false
|
let treeExitObserved = false
|
||||||
let treeExitObservation: Promise<void> | undefined
|
let treeExitObservation: Promise<void> | undefined
|
||||||
let settled = false
|
let settled = false
|
||||||
@@ -427,7 +426,6 @@ export function spawnSubprocess(spec: SubprocessSpawnSpec, internals: SpawnInter
|
|||||||
treeExitObservation ??= (async () => {
|
treeExitObservation ??= (async () => {
|
||||||
while (treeAlive()) await sleepTick()
|
while (treeAlive()) await sleepTick()
|
||||||
treeExitObserved = true
|
treeExitObserved = true
|
||||||
terminationStarted = true
|
|
||||||
graceTimer?.cancel()
|
graceTimer?.cancel()
|
||||||
graceTimer = undefined
|
graceTimer = undefined
|
||||||
})()
|
})()
|
||||||
@@ -447,11 +445,11 @@ export function spawnSubprocess(spec: SubprocessSpawnSpec, internals: SpawnInter
|
|||||||
}
|
}
|
||||||
|
|
||||||
const terminate = (): void => {
|
const terminate = (): void => {
|
||||||
if (terminationStarted) return
|
if (treeExitObserved || graceTimer !== undefined) return
|
||||||
terminationStarted = true
|
|
||||||
// Observe from the first termination tier onward, even when inherited
|
// Observe from the first termination tier onward, even when inherited
|
||||||
// pipes delay `done` and no consumer has begun its own teardown wait.
|
// pipes delay `done` and no consumer has begun its own teardown wait.
|
||||||
void observeTreeExit()
|
void observeTreeExit()
|
||||||
|
// oxlint-disable-next-line typescript/no-unnecessary-condition -- observer can record absence before its first await.
|
||||||
if (treeExitObserved) return
|
if (treeExitObserved) return
|
||||||
kill('SIGTERM')
|
kill('SIGTERM')
|
||||||
// The escalation must survive direct-child settlement — the leader dying
|
// The escalation must survive direct-child settlement — the leader dying
|
||||||
|
|||||||
Reference in New Issue
Block a user