mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-08 01:43:07 +00:00
fix(codex): ignore late app-server writes during disconnect (#1748)
* fix(codex): ignore late app-server writes during disconnect * fix(codex): scope app-server responses to their process --------- Co-authored-by: huxiang <huxiang@myai.tech>
This commit is contained in:
@@ -224,6 +224,11 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
});
|
||||
this.process = child;
|
||||
|
||||
child.stdin.on('error', (error) => {
|
||||
if (this.process !== child) return;
|
||||
logger.debug('[CodexAppServer] stdin error', error);
|
||||
});
|
||||
|
||||
child.stdout.setEncoding('utf8');
|
||||
child.stdout.on('data', (chunk) => {
|
||||
if (this.process === child) this.feed(chunk);
|
||||
@@ -677,10 +682,13 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
|
||||
if ('id' in message && message.id !== undefined) {
|
||||
const requestId = message.id;
|
||||
const sourceProcess = this.process;
|
||||
void this.handleIncomingRequest({
|
||||
id: requestId,
|
||||
method,
|
||||
params
|
||||
}, sourceProcess).catch((error) => {
|
||||
logger.debug('[CodexAppServer] Error handling incoming request', error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -694,7 +702,10 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
}
|
||||
}
|
||||
|
||||
private async handleIncomingRequest(request: { id: unknown; method: string; params?: unknown }): Promise<void> {
|
||||
private async handleIncomingRequest(
|
||||
request: { id: unknown; method: string; params?: unknown },
|
||||
sourceProcess: ChildProcessWithoutNullStreams | null
|
||||
): Promise<void> {
|
||||
const responseId = typeof request.id === 'number' || typeof request.id === 'string'
|
||||
? request.id
|
||||
: null;
|
||||
@@ -707,7 +718,7 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
code: -32601,
|
||||
message: `Method not found: ${request.method}`
|
||||
}
|
||||
} satisfies JsonRpcLiteResponse);
|
||||
} satisfies JsonRpcLiteResponse, sourceProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -716,7 +727,7 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
this.writePayload({
|
||||
id: responseId,
|
||||
result
|
||||
} satisfies JsonRpcLiteResponse);
|
||||
} satisfies JsonRpcLiteResponse, sourceProcess);
|
||||
} catch (error) {
|
||||
this.writePayload({
|
||||
id: responseId,
|
||||
@@ -724,7 +735,7 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
code: -32603,
|
||||
message: error instanceof Error ? error.message : 'Internal error'
|
||||
}
|
||||
} satisfies JsonRpcLiteResponse);
|
||||
} satisfies JsonRpcLiteResponse, sourceProcess);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,9 +775,28 @@ export class CodexAppServerClient extends JsonLineParser {
|
||||
return error;
|
||||
}
|
||||
|
||||
private writePayload(payload: JsonRpcLiteRequest | JsonRpcLiteNotification | JsonRpcLiteResponse): void {
|
||||
private writePayload(
|
||||
payload: JsonRpcLiteRequest | JsonRpcLiteNotification | JsonRpcLiteResponse,
|
||||
targetProcess: ChildProcessWithoutNullStreams | null = this.process
|
||||
): void {
|
||||
if (!targetProcess || targetProcess !== this.process) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stdin = targetProcess.stdin;
|
||||
if (!stdin || stdin.destroyed || stdin.writableEnded || stdin.writable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
const serialized = JSON.stringify(payload);
|
||||
this.process?.stdin.write(`${serialized}\n`);
|
||||
try {
|
||||
stdin.write(`${serialized}\n`);
|
||||
} catch (error) {
|
||||
// The app-server can close stdin while an async request handler is
|
||||
// still completing. Dropping that late response is safe; the
|
||||
// transport is already unavailable and must not crash the runner.
|
||||
logger.debug('[CodexAppServer] Ignoring payload write after process shutdown', error);
|
||||
}
|
||||
}
|
||||
|
||||
private resetParserState(): void {
|
||||
|
||||
Reference in New Issue
Block a user