perf(ext/node): lazily listen to the abort signal of request object (#29071)

This commit is contained in:
Yoshiya Hinosawa 2025-04-29 20:44:09 +09:00 committed by GitHub
parent 2221cf3e7c
commit d1f7969570
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -130,15 +130,18 @@ function validateHost(host, name) {
const INVALID_PATH_REGEX = /[^\u0021-\u00ff]/; const INVALID_PATH_REGEX = /[^\u0021-\u00ff]/;
const kError = Symbol("kError"); const kError = Symbol("kError");
const kBindToAbortSignal = Symbol("kBindToAbortSignal");
class FakeSocket extends EventEmitter { class FakeSocket extends EventEmitter {
/** Stores the underlying request for lazily binding to abort signal */
#request: Request | undefined;
constructor( constructor(
opts: { opts: {
encrypted?: boolean | undefined; encrypted?: boolean | undefined;
remotePort?: number | undefined; remotePort?: number | undefined;
remoteAddress?: string | undefined; remoteAddress?: string | undefined;
reader?: ReadableStreamDefaultReader | undefined; reader?: ReadableStreamDefaultReader | undefined;
signal?: AbortSignal | undefined; request?: Request;
} = {}, } = {},
) { ) {
super(); super();
@ -148,8 +151,13 @@ class FakeSocket extends EventEmitter {
this.reader = opts.reader; this.reader = opts.reader;
this.writable = true; this.writable = true;
this.readable = true; this.readable = true;
opts.signal?.addEventListener("abort", () => { this.#request = opts.request;
this.emit("error", opts.signal?.reason ?? new Error("aborted")); }
[kBindToAbortSignal]() {
const signal = this.#request?.signal;
signal?.addEventListener("abort", () => {
this.emit("error", signal.reason);
this.emit("close"); this.emit("close");
}, { once: true }); }, { once: true });
} }
@ -1499,9 +1507,14 @@ export const ServerResponse = function (
this._readable = readable; this._readable = readable;
this._resolve = resolve; this._resolve = resolve;
this.socket = socket; this.socket = socket;
this.on("newListener", (event) => {
if (event === "close") {
this.socket?.[kBindToAbortSignal]();
this.socket?.on("close", () => { this.socket?.on("close", () => {
if (!this.finished) { if (!this.finished) {
this.end(); this.emit("close");
}
});
} }
}); });
this._header = ""; this._header = "";
@ -1936,7 +1949,7 @@ export class ServerImpl extends EventEmitter {
remotePort: info.remoteAddr.port, remotePort: info.remoteAddr.port,
encrypted: this._encrypted, encrypted: this._encrypted,
reader: request.body?.getReader(), reader: request.body?.getReader(),
signal: request.signal, request,
}); });
const req = new IncomingMessageForServer(socket); const req = new IncomingMessageForServer(socket);