[feat] override stdout & stderr in worker_thread for debug worker
According to the research based on the issue at https://github.com/jimmywarting/await-sync/issues/1#issuecomment-1538762664
Worker threads in Node.js send their standard IO to the main thread for processing. When synchronous operations are implemented, the blocking of these operations can cause the logs of these worker threads to be synchronized and output only after the computation results are completed.
Similarly, following the implementation of whatwg-workers, by rewriting the write methods of stdout and stderr streams within worker threads, it is possible to allow the standard input and standard error within the worker threads to be directly written into the streams.
// caused by https://github.com/nodejs/node/blob/0b3fcfcf351fba9f29234976eeec4afb09ae2cc0/lib/internal/worker/io.js#L360
// override process write to make stdout and stderr work in worker thread
function overrideProcess4WorkThread() {
for (const [i, stream] of [process.stdout, process.stderr].entries()) {
// process.stdout.fd === 1 & process.stderr.fd === 2 . In Worker threads, this field does not exist.
const fd = i + 1
const streamOriginWritev = stream._writev?.bind(stream)
stream._writev = (chunks, cb) => {
if (chunks.length === 0) {
return
}
const chunk = chunks.pop()!
// type-coverage:ignore-next-line -- we can't control
fs.write(fd, chunk.chunk as string, null, chunk.encoding, err => {
if (err) cb(err)
else if (chunks.length === 0) cb()
else streamOriginWritev?.(chunks, cb)
})
}
}
}
and test demo output
If allowed, I'm glad to raise a pr
Well done, a PR with test cases will be appreciated.
Keep in mind, the override should be executed only once if possible.
Okay, I will add some test cases later and check whether this override only takes effect within the worker thread.
https://github.com/fisker/make-synchronized/pull/10 😄 Thanks for the idea!