fix(pool): prevent writing to closed worker (#9023) · vitest-dev/vitest@042c60c

2 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -76,8 +76,9 @@ export class Pool {

7676

const activeTask = { task, resolver, method, cancelTask }

7777

this.activeTasks.push(activeTask)

7878
79+

// active tasks receive cancel signal and shut down gracefully

7980

async function cancelTask() {

80-

await runner.stop()

81+

await runner.waitForTerminated()

8182

resolver.reject(new Error('Cancelled'))

8283

}

8384
Original file line numberDiff line numberDiff line change

@@ -30,6 +30,7 @@ export class PoolRunner {

3030
3131

private _state: RunnerState = RunnerState.IDLE

3232

private _operationLock: DeferPromise<void> | null = null

33+

private _terminatePromise: DeferPromise<void> = createDefer()

3334
3435

private _eventEmitter: EventEmitter<{

3536

message: [WorkerResponse]

@@ -44,6 +45,10 @@ export class PoolRunner {

4445

return this._state === RunnerState.STOPPED

4546

}

4647
48+

public waitForTerminated(): Promise<void> {

49+

return this._terminatePromise

50+

}

51+
4752

public get isStarted(): boolean {

4853

return this._state === RunnerState.STARTED

4954

}

@@ -58,7 +63,11 @@ export class PoolRunner {

5863

}),

5964

{

6065

eventNames: ['onCancel'],

61-

post: request => this.postMessage(request),

66+

post: (request) => {

67+

if (this._state !== RunnerState.STOPPING && this._state !== RunnerState.STOPPED) {

68+

this.postMessage(request)

69+

}

70+

},

6271

on: callback => this._eventEmitter.on('rpc', callback),

6372

timeout: -1,

6473

},

@@ -199,6 +208,7 @@ export class PoolRunner {

199208

finally {

200209

this._operationLock.resolve()

201210

this._operationLock = null

211+

this._terminatePromise.resolve()

202212

}

203213

}

204214