python service managment on client, port configuration

This commit is contained in:
michalcourson
2026-02-24 18:08:58 -05:00
parent d49ac95fa2
commit 47cdaa76b6
26 changed files with 244 additions and 67 deletions

View File

@ -0,0 +1,79 @@
import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
import path from 'path';
export default class PythonSubprocessManager {
// eslint-disable-next-line no-use-before-define
public static instance: PythonSubprocessManager | null = null;
private process: ChildProcessWithoutNullStreams | null = null;
private scriptPath: string;
private working_dir: string = path.join(
__dirname,
'..',
'..',
'..',
'audio-service',
);
public portNumber: number | null = null;
constructor(scriptPath: string) {
this.scriptPath = scriptPath;
PythonSubprocessManager.instance = this;
}
start(args: string[] = []): void {
if (this.process) {
throw new Error('Process already running.');
}
console.log(`Using Python working directory at: ${this.working_dir}`);
console.log(`Starting Python subprocess with script: ${this.scriptPath}`);
this.process = spawn(
'venv/Scripts/python.exe',
[this.scriptPath, ...args],
{
cwd: this.working_dir,
detached: false,
stdio: 'pipe',
},
);
this.process.stdout.on('data', (data: Buffer) => {
console.log(`Python stdout: ${data.toString()}`);
});
this.process.stderr.on('data', (data: Buffer) => {
console.error(`Python stderr: ${data.toString()}`);
const lines = data.toString().split('\n');
// eslint-disable-next-line no-restricted-syntax
for (const line of lines) {
const match = line.match(/Running on .*:(\d+)/);
if (match) {
const port = parseInt(match[1], 10);
console.log(`Detected port: ${port}`);
this.portNumber = port;
}
}
});
this.process.on('exit', () => {
console.log('Python subprocess exited.');
this.process = null;
});
}
stop(): void {
if (this.process) {
this.process.kill();
this.process = null;
}
}
restart(args: string[] = []): void {
this.stop();
this.start(args);
}
isHealthy(): boolean {
return !!this.process && !this.process.killed;
}
}