···11+---
22+'fetch-nodeshim': patch
33+---
44+55+Limit state in which `incoming.socket` is unrefed and instead `.ref()` it when the body is being read, and `.unref()` it again when reading stops.
+19
src/fetch.ts
···11import { Stream, Readable, pipeline } from 'node:stream';
22+import { Socket } from 'node:net';
23import * as https from 'node:https';
34import * as http from 'node:http';
45import * as url from 'node:url';
···110111 if (params.redirected)
111112 Object.defineProperty(response, 'redirected', { value: params.redirected });
112113 return response;
114114+}
115115+116116+function attachRefLifetime(body: Readable, socket: Socket): void {
117117+ const { _read } = body;
118118+ body.on('close', () => {
119119+ socket.unref();
120120+ });
121121+ body._read = function _readRef(...args: Parameters<Readable['_read']>) {
122122+ body._read = _read;
123123+ socket.ref();
124124+ return _read.apply(this, args);
125125+ };
113126}
114127115128async function _fetch(
···255268 init.headers.set('Content-Encoding', encoding);
256269 body = pipeline(body, createContentDecoder(encoding), destroy);
257270 outgoing.on('error', destroy);
271271+ }
272272+273273+ // Re-ref the socket when the body starts being consumed to prevent
274274+ // early process exit, then unref when done to allow normal exit.
275275+ if (body != null) {
276276+ attachRefLifetime(body, incoming.socket);
258277 }
259278260279 resolve(