33 lines
1.1 KiB
JavaScript
33 lines
1.1 KiB
JavaScript
// Observe at launch: a renderer can close before the native process and its
|
|
// stdio pipes. Playwright's driver exit cleanup tree-kills until that close.
|
|
function observeProcessClose(child) {
|
|
let closed = false
|
|
const completion = new Promise(resolve => child.once('close', () => {
|
|
closed = true
|
|
resolve()
|
|
}))
|
|
// Windows descendants can inherit pipe handles and postpone 'close' after
|
|
// the launch process exits. Release our handles, never kill descendants.
|
|
const releasePipes = () => {
|
|
for (const stream of child.stdio) stream?.destroy()
|
|
}
|
|
child.once('exit', releasePipes)
|
|
if (child.exitCode !== null || child.signalCode !== null) releasePipes()
|
|
return async function waitForClose(timeoutMs = 120_000) {
|
|
if (closed) return
|
|
let timer
|
|
try {
|
|
await Promise.race([
|
|
completion,
|
|
new Promise((_, reject) => {
|
|
timer = setTimeout(() => reject(new Error('Electron process did not close after update hand-off')), timeoutMs)
|
|
}),
|
|
])
|
|
} finally {
|
|
clearTimeout(timer)
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = { observeProcessClose }
|