Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 8a309a3

Browse files
committed
feat(nitro-node): add stdio and event handler for nitro subprocess
This expose exit code, termination signal, and stdio for nitro subprocess This should help solving #369
1 parent 9bd5af3 commit 8a309a3

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

nitro-node/src/nitro.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from "node:fs";
22
import path from "node:path";
3+
import stream from "node:stream";
34
import { ChildProcessWithoutNullStreams, spawn } from "node:child_process";
45
import tcpPortUsed from "tcp-port-used";
56
import fetchRT from "fetch-retry";
@@ -10,6 +11,8 @@ import {
1011
NitroModelOperationResponse,
1112
NitroModelInitOptions,
1213
NitroProcessInfo,
14+
NitroProcessEventHandler,
15+
NitroProcessStdioHanler,
1316
} from "./types";
1417
import { downloadNitro } from "./scripts";
1518
import { checkMagicBytes, getResourcesInfo } from "./utils";
@@ -50,6 +53,28 @@ const getNitroProcessInfo = (subprocess: any): NitroProcessInfo => ({
5053
isRunning: subprocess != null,
5154
});
5255
const getCurrentNitroProcessInfo = () => getNitroProcessInfo(subprocess);
56+
// Default event handler: do nothing
57+
let processEventHandler: NitroProcessEventHandler = {};
58+
// Default stdio handler: log stdout and stderr
59+
let processStdioHandler: NitroProcessStdioHanler = {
60+
stdout: (stdout: stream.Readable | null | undefined) => {
61+
stdout?.on("data", (data: any) => {
62+
log(`[NITRO]::Debug: ${data}`);
63+
});
64+
},
65+
stderr: (stderr: stream.Readable | null | undefined) => {
66+
stderr?.on("data", (data: any) => {
67+
log(`[NITRO]::Error: ${data}`);
68+
});
69+
},
70+
};
71+
72+
const registerEventHandler = (handler: NitroProcessEventHandler) => {
73+
processEventHandler = handler;
74+
};
75+
const registerStdioHandler = (handler: NitroProcessStdioHanler) => {
76+
processStdioHandler = handler;
77+
};
5378

5479
// The current model file url
5580
let currentModelFile: string = "";
@@ -378,16 +403,16 @@ function spawnNitroProcess(
378403
);
379404

380405
// Handle subprocess output
381-
subprocess.stdout.on("data", (data: any) => {
382-
log(`[NITRO]::Debug: ${data}`);
383-
});
384-
385-
subprocess.stderr.on("data", (data: any) => {
386-
log(`[NITRO]::Error: ${data}`);
387-
});
406+
processStdioHandler.stdout(subprocess.stdout);
407+
processStdioHandler.stderr(subprocess.stderr);
408+
// Handle events
409+
let evt: keyof NitroProcessEventHandler;
410+
for (evt in processEventHandler) {
411+
subprocess.on(evt, processEventHandler[evt]!);
412+
}
388413

389-
subprocess.on("close", (code: any) => {
390-
log(`[NITRO]::Debug: Nitro exited with code: ${code}`);
414+
subprocess.on("close", (code: number, signal: string) => {
415+
log(`[NITRO]::Debug: Nitro exited with code: ${code}, signal: ${signal}`);
391416
subprocess = undefined;
392417
reject(`child process exited with code ${code}`);
393418
});
@@ -411,6 +436,8 @@ export {
411436
getCurrentNitroProcessInfo,
412437
getBinPath,
413438
setBinPath,
439+
registerStdioHandler,
440+
registerEventHandler,
414441
initialize,
415442
stopModel,
416443
runModel,

nitro-node/src/types/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import { ChildProcessWithoutNullStreams } from "node:child_process";
2+
import net from "node:net";
3+
import stream from "node:stream";
4+
15
/**
26
* The response from the initModel function.
37
* @property error - An error message if the model fails to load.
@@ -19,6 +23,27 @@ export interface NitroProcessInfo {
1923
isRunning: boolean;
2024
}
2125

26+
export interface NitroProcessEventHandler {
27+
close?: (code: number, signal: string) => void;
28+
disconnect?: () => void;
29+
error?: (e: Error) => void;
30+
exit?: (code: number, signal: string) => void;
31+
message?: (
32+
message: object,
33+
sendHandle: net.Socket | net.Server | undefined,
34+
) => void;
35+
spawn?: () => void;
36+
}
37+
38+
export interface NitroProcessStdioHanler {
39+
stdout: (_: stream.Readable | null | undefined) => void;
40+
stderr: (_: stream.Readable | null | undefined) => void;
41+
}
42+
43+
export interface NitroProcessCloseHandler {
44+
(code: number, signal: string): void;
45+
}
46+
2247
/**
2348
* Setting for prompts when inferencing with Nitro
2449
*/

0 commit comments

Comments
 (0)