add a interface for process launching

This is to allow external usage of the library to control process launching (and, for one example, place processes we launch into special cgroups.)
This commit is contained in:
Lily Tsuru 2024-11-02 02:52:43 -04:00
parent e3123252a4
commit d19f649a55
2 changed files with 80 additions and 0 deletions

44
src/DefaultProcess.ts Normal file
View file

@ -0,0 +1,44 @@
// Default process implementation.
// This uses execa like the current code, but conforms to our abstration :)
import EventEmitter from "events";
import { IProcess, IProcessLauncher, ProcessLaunchOptions } from "./ProcessInterface";
import { execaCommand } from "execa";
import { Readable, Writable } from "stream";
class DefaultProcess extends EventEmitter implements IProcess {
private process;
stdin: Writable | null = null;
stdout: Readable | null = null;
stderr: Readable | null = null;
constructor(command: string, opts?: ProcessLaunchOptions) {
super();
this.process = execaCommand(command, opts);
this.stdin = this.process.stdin;
this.stdout = this.process.stdout;
this.stderr = this.process.stderr;
let self = this;
this.process.on('spawn', () => {
self.emit('spawn');
});
this.process.on('exit', (code) => {
self.emit('exit', code);
});
}
kill(signal?: number | NodeJS.Signals): boolean {
return this.process.kill(signal);
}
}
export class DefaultProcessLauncher implements IProcessLauncher {
launch(command: string, opts?: ProcessLaunchOptions | undefined): IProcess {
return new DefaultProcess(command, opts);
}
}

36
src/ProcessInterface.ts Normal file
View file

@ -0,0 +1,36 @@
import {type Stream, EventEmitter, Readable, Writable} from 'node:stream';
export type StdioOption =
| 'pipe'
| 'overlapped'
| 'ipc'
| 'ignore'
| 'inherit'
| Stream
| number
| undefined;
// subset of options. FIXME: Add more!!!
export interface ProcessLaunchOptions {
stdin?: StdioOption,
stdout?: StdioOption,
stderr?: StdioOption
}
export interface IProcess extends EventEmitter {
stdin: Writable | null;
stdout: Readable | null;
stderr: Readable | null;
// Escape hatch; only use this if you have no choice
//native() : any;
kill(signal?: number | NodeJS.Signals): boolean;
}
// Launches a processs.
export interface IProcessLauncher {
launch(command: string, opts?: ProcessLaunchOptions) : IProcess;
}