UNPKG

@travetto/compiler

Version:

The compiler infrastructure for the Travetto framework

75 lines (63 loc) 2 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import type { ManifestContext } from '@travetto/manifest'; import { Log, Logger } from '../log.ts'; import { CommonUtil } from '../util.ts'; export class ProcessHandle { #file: string; #log: Logger; constructor(ctx: ManifestContext, name: string) { this.#file = CommonUtil.resolveWorkspace(ctx, ctx.build.toolFolder, `${name}.pid`); this.#log = Log.scoped(`process-handle.${name}`); } async writePid(pid: number): Promise<void> { await fs.mkdir(path.dirname(this.#file), { recursive: true }); return fs.writeFile(this.#file, JSON.stringify(pid), 'utf8'); } getPid(): Promise<number | undefined> { return fs.readFile(this.#file, 'utf8') .then(v => +v > 0 ? +v : undefined, () => undefined); } async isRunning(): Promise<boolean> { const pid = await this.getPid(); if (!pid) { return false; } try { process.kill(pid, 0); // See if process is still running this.#log.debug('Is running', pid); return true; } catch { this.#log.debug('Is not running', pid); } return false; // Not running } async kill(): Promise<boolean> { const pid = await this.getPid(); if (pid && await this.isRunning()) { try { this.#log.debug('Killing', pid); return process.kill(pid); } catch { } } return false; } async ensureKilled(gracePeriod: number = 3000): Promise<boolean> { const start = Date.now(); const pid = await this.getPid(); if (!pid) { return false; } this.#log.debug('Ensuring Killed', pid); while ((Date.now() - start) < gracePeriod) { // Ensure its done if (!await this.isRunning()) { return true; } await CommonUtil.blockingTimeout(100); } try { this.#log.debug('Force Killing', pid); process.kill(pid); // Force kill } catch { } this.#log.debug('Did Kill', this.#file, !!pid); return true; } }