You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tinypool throws Error: write EPIPE errors randomly on Vitest when running under heavy load. I can reproduce this issue 3/10 times on private pnpm monorepo with 3 packages running vitest@1.3.0. Using stress unix command helps reproducing the issue.
Minimal reproduction
This is caused by race condition so reproducing is flaky. I'm able to reproduce this quite easily locally.
importTinypoolfrom'./dist/esm/index.js'constmessages=[]constlisteners=[]letsetRunningconstisRunning=newPromise((r)=>(setRunning=r))constchannel={onMessage: (listener)=>listeners.push(listener),postMessage: (message)=>{if(message==='WORKER_START')setRunning()elsemessages.push(message)},}constpool=newTinypool({runtime: 'child_process',minThreads: 10,maxThreads: 10,filename: newURL('./worker.mjs',import.meta.url).href,})pool.run({},{ channel })awaitisRunninglisteners.forEach((listener)=>listener('Hello from main thread'))pool.destroy()listeners.forEach((listener)=>listener('Hello from main thread'))// <-- Key part is hereconsole.log('Done',messages)
exportdefaultasyncfunctionrun(){process.send('WORKER_START')returnnewPromise((resolve)=>{process.on('message',(message)=>{// Ignore Tinypool's internal messagesif(message?.__tinypool_worker_message__)returnprocess.send({received: message,response: 'Hello from worker'})resolve()})})}
ari ~/Git/tinypool (fix/prevent-write-to-terminating-worker) $ node example.mjs
Done [
{ received: 'Hello from main thread', response: 'Hello from worker' }
]
Done [
{ received: 'Hello from main thread', response: 'Hello from worker' }
]
Done [
{ received: 'Hello from main thread', response: 'Hello from worker' }
]
node:events:496
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at target._send (node:internal/child_process:879:20)
at target.send (node:internal/child_process:752:19)
at ProcessWorker.send (file:///xyz/tinypool/dist/esm/index.js:218:18)
at file:///xyz/tinypool/dist/esm/index.js:212:12
at file:///xyz/tinypool/example.mjs:29:33
at Array.forEach (<anonymous>)
at file:///xyz/tinypool/example.mjs:29:11
Emitted 'error' event on Tinypool instance at:
at EventEmitterReferencingAsyncResource.runInAsyncScope (node:async_hooks:206:9)
at Tinypool.emit (file:///xyz/tinypool/dist/esm/index.js:61:31)
at file:///xyz/tinypool/dist/esm/index.js:752:30
at ChildProcess.<anonymous> (file:///xyz/tinypool/dist/esm/index.js:242:16)
at ChildProcess.emit (node:events:530:35)
at node:internal/child_process:883:39
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
errno: -32,
code: 'EPIPE',
syscall: 'write'
}
Tinypool throws
Error: write EPIPE
errors randomly on Vitest when running under heavy load. I can reproduce this issue 3/10 times on privatepnpm
monorepo with 3 packages runningvitest@1.3.0
. Usingstress
unix command helps reproducing the issue.Minimal reproduction
This is caused by race condition so reproducing is flaky. I'm able to reproduce this quite easily locally.
Error is coming from here:
tinypool/src/runtime/process-worker.ts
Lines 62 to 65 in c045ecf
Vitest's channel is simple
EventEmitter
: https://github.com/vitest-dev/vitest/blob/fc26f562a7faf03b9b8810b6ba374346364a9259/packages/vitest/src/node/pools/forks.ts#L20-L23. The erroneous message seems to be file transform request which resolves after tests have passed and worker is closing (cc. @sheremet-va). Thethis.process.connected
returnstrue
andthis.process.channel
is still defined when the error happens. 🤷As work-around we can keep track of if
this.terminate
has been called and ignore all channel's messages after that.The text was updated successfully, but these errors were encountered: