Skip to content

Commit 06fc217

Browse files
authored
fix: memory leak in entry.server (#14200)
1 parent 06519e2 commit 06fc217

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

.changeset/rotten-parents-care.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
fix: memory leak in default entry.server

packages/react-router-dev/config/defaults/entry.server.node.tsx

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function handleRequest(
1414
responseStatusCode: number,
1515
responseHeaders: Headers,
1616
routerContext: EntryContext,
17-
loadContext: AppLoadContext,
17+
loadContext: AppLoadContext
1818
// If you have middleware enabled:
1919
// loadContext: unstable_RouterContextProvider
2020
) {
@@ -29,24 +29,38 @@ export default function handleRequest(
2929
? "onAllReady"
3030
: "onShellReady";
3131

32+
// Abort the rendering stream after the `streamTimeout` so it has time to
33+
// flush down the rejected boundaries
34+
let timeoutId: ReturnType<typeof setTimeout> | undefined = setTimeout(
35+
() => abort(),
36+
streamTimeout + 1000
37+
);
38+
3239
const { pipe, abort } = renderToPipeableStream(
3340
<ServerRouter context={routerContext} url={request.url} />,
3441
{
3542
[readyOption]() {
3643
shellRendered = true;
37-
const body = new PassThrough();
44+
const body = new PassThrough({
45+
final(callback) {
46+
// Clear the timeout to prevent retaining the closure and memory leak
47+
clearTimeout(timeoutId);
48+
timeoutId = undefined;
49+
callback();
50+
},
51+
});
3852
const stream = createReadableStreamFromReadable(body);
3953

4054
responseHeaders.set("Content-Type", "text/html");
4155

56+
pipe(body);
57+
4258
resolve(
4359
new Response(stream, {
4460
headers: responseHeaders,
4561
status: responseStatusCode,
46-
}),
62+
})
4763
);
48-
49-
pipe(body);
5064
},
5165
onShellError(error: unknown) {
5266
reject(error);
@@ -60,11 +74,7 @@ export default function handleRequest(
6074
console.error(error);
6175
}
6276
},
63-
},
77+
}
6478
);
65-
66-
// Abort the rendering stream after the `streamTimeout` so it has time to
67-
// flush down the rejected boundaries
68-
setTimeout(abort, streamTimeout + 1000);
6979
});
7080
}

0 commit comments

Comments
 (0)