synckit icon indicating copy to clipboard operation
synckit copied to clipboard

[feat] override stdout & stderr in worker_thread for debug worker

Open yangxiaolang opened this issue 1 year ago • 3 comments

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 image

If allowed, I'm glad to raise a pr

yangxiaolang avatar Jan 23 '24 14:01 yangxiaolang

Well done, a PR with test cases will be appreciated.

Keep in mind, the override should be executed only once if possible.

JounQin avatar Jan 23 '24 15:01 JounQin

Okay, I will add some test cases later and check whether this override only takes effect within the worker thread.

yangxiaolang avatar Jan 23 '24 15:01 yangxiaolang

https://github.com/fisker/make-synchronized/pull/10 😄 Thanks for the idea!

fisker avatar Jan 23 '24 17:01 fisker