Skip to content

Commit 2673c3b

Browse files
authoredSep 3, 2024··
fix(vitest): dispose vmForks listeners to avoid memory leak (#6448)
1 parent 0499a31 commit 2673c3b

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed
 

‎packages/vitest/src/runtime/worker.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import type { ContextRPC, WorkerGlobalState } from '../types/worker'
77
import { setupInspect } from './inspector'
88
import { createRuntimeRpc, rpcDone } from './rpc'
99
import type { VitestWorker } from './workers/types'
10+
import { disposeInternalListeners } from './workers/utils'
1011

1112
if (isChildProcess()) {
1213
setProcessTitle(`vitest ${poolId}`)
1314
}
1415

1516
// this is what every pool executes when running tests
1617
async function execute(mehtod: 'run' | 'collect', ctx: ContextRPC) {
18+
disposeInternalListeners()
19+
1720
const prepareStart = performance.now()
1821

1922
const inspectorCleanup = setupInspect(ctx)

‎packages/vitest/src/runtime/workers/utils.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const REGEXP_WRAP_PREFIX = '$$vitest:'
99
// Store global APIs in case process is overwritten by tests
1010
const processSend = process.send?.bind(process)
1111
const processOn = process.on?.bind(process)
12+
const processOff = process.off?.bind(process)
13+
const dispose: (() => void)[] = []
1214

1315
export function createThreadsRpcOptions({
1416
port,
@@ -23,6 +25,16 @@ export function createThreadsRpcOptions({
2325
}
2426
}
2527

28+
export function disposeInternalListeners() {
29+
for (const fn of dispose) {
30+
try {
31+
fn()
32+
}
33+
catch {}
34+
}
35+
dispose.length = 0
36+
}
37+
2638
export function createForksRpcOptions(
2739
nodeV8: typeof import('v8'),
2840
): WorkerRpcOptions {
@@ -33,14 +45,16 @@ export function createForksRpcOptions(
3345
processSend!(v)
3446
},
3547
on(fn) {
36-
processOn('message', (message: any, ...extras: any) => {
48+
const handler = (message: any, ...extras: any) => {
3749
// Do not react on Tinypool's internal messaging
3850
if ((message as TinypoolWorkerMessage)?.__tinypool_worker_message__) {
3951
return
4052
}
4153

4254
return fn(message, ...extras)
43-
})
55+
}
56+
processOn('message', handler)
57+
dispose.push(() => processOff('message', handler))
4458
},
4559
}
4660
}

0 commit comments

Comments
 (0)
Please sign in to comment.