Files
orca/config/scripts/node-server-verifier-daemon-cleanup.ts
T

71 lines
2.1 KiB
TypeScript

import { existsSync, readdirSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { DaemonClient } from '../../src/main/daemon/client'
import { getDaemonSocketPath, getDaemonTokenPath } from '../../src/main/daemon/daemon-spawner'
export async function stopNodeServerVerifierDaemons(dataPath: string): Promise<void> {
const daemonPath = join(dataPath, 'daemon')
if (!existsSync(daemonPath)) {
return
}
const shutdowns: Promise<void>[] = []
for (const entry of readdirSync(daemonPath)) {
const match = /^daemon-v(\d+)\.pid$/.exec(entry)
if (!match) {
continue
}
try {
const record = JSON.parse(readFileSync(join(daemonPath, entry), 'utf8')) as { pid?: unknown }
if (typeof record.pid === 'number' && Number.isInteger(record.pid)) {
shutdowns.push(shutdownDaemon(daemonPath, Number(match[1]), record.pid))
}
} catch {
// The isolated verifier directory can contain a daemon that already retired.
}
}
await Promise.all(shutdowns)
}
async function shutdownDaemon(
daemonPath: string,
protocolVersion: number,
pid: number
): Promise<void> {
const client = new DaemonClient({
socketPath: getDaemonSocketPath(daemonPath, protocolVersion),
tokenPath: getDaemonTokenPath(daemonPath, protocolVersion),
protocolVersion
})
let requestError: unknown
try {
await client.ensureConnectedWithin(5_000)
await client.request('shutdown', { killSessions: true }, 10_000)
} catch (error) {
requestError = error
} finally {
client.disconnect()
}
try {
await waitForProcessExit(pid)
} catch (error) {
if (requestError) {
throw new AggregateError([requestError, error], `terminal daemon ${pid} cleanup failed`)
}
throw error
}
}
async function waitForProcessExit(pid: number): Promise<void> {
const deadline = Date.now() + 10_000
while (Date.now() < deadline) {
try {
process.kill(pid, 0)
} catch {
return
}
await new Promise((resolveWait) => setTimeout(resolveWait, 100))
}
throw new Error(`terminal daemon ${pid} did not exit after the shutdown request`)
}