0

I'm using child_process.fork in a NodeJS API server. Here's how I call it:

const { fork } = require('child_process');

const dequeuingChild = fork('dequeue-child.js', null, {stdio: 'inherit', detached: false});

...

// inside some function
dequeuingChild.send({ action: ACTION.DEQUEUE }); // btw is this .send() and counterpart .on('message') sync?
...

I have read from the doc about the detached option which says:

On non-Windows platforms ... the child process will be made the leader of a new process group and session...

my concern is what's included in this process group, session, etc. I mean, does it mean that a non detached child process still shares the resources of the master? Can long running codes running in the non detached child still impact the performance of the master process?

I read somewhere that internally, the C++ part of NodeJS creates threads where it delegates the async operations to, and that part is blocking. Does a non-detached child process share those threads (w/c means they'll block events from master process too)? And is there a difference in memory usage/sharing from detached/attached child process?

I'm asking this because I have in my master process the web server which should receive and enqueue (awaited async) requests as fast as it can, then I delegate the dequeue part, which performs more processing and could run slower than the enqueue part to a pre-forked child process (via .send()). So I want my web server (receiving) part to run as fast as it can and not let the child process bog down or affect it. The child doesn't have to stay when I exit the master, actually I exit it when the master is exited.

Because I don't understand the impact, I'm torn, should I use the detached option or not?

Thank you very much!

Mon
  • 1,010
  • 1
  • 11
  • 19

1 Answers1

0

Does a non-detached child process share those threads (w/c means they'll block events from master process too)?

No. A child_process (whether detached or not) does not share any threads or memory with the original process. A WorkerThread does share some infrastructure with the parent, but not a child process. The child is its own OS process and has its own separate V8 engine and separate libuv and event loop.

And is there a difference in memory usage/sharing from detached/attached child process?

No.

I'm asking this because I have in my master process the web server which should receive and enqueue (awaited async) requests as fast as it can, then I delegate the dequeue part, which performs more processing and could run slower than the enqueue part to a pre-forked child process (via .send()). So I want my web server (receiving) part to run as fast as it can and not let the child process bog down or affect it.

This won't perform any different whether the child is detached or not.

The child doesn't have to stay when I exit the master, actually I exit it when the master is exited.

Then, don't use detached.

Because I don't understand the impact, I'm torn, should I use the detached option or not?

I don't see any reason for you to use detached. If you don't want the child to keep running independently after the parent has exited, then there's really no reason to use it.

Can long running codes running in the non detached child still impact the performance of the master process?

Code in any child, whether detached or not, can impact the performance of the parent process just because they are both competing for CPU cycles from the OS. But, this is no different whether detached or not.

FYI, the most common thing you might share with a child process is stdio or stdout (though you have options as to whether those are shared or not when you create the child), but whether those are shared or not should not impact the performance one way or the other of what you describe.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • The docs also show that it's possible to send a server or socket from the parent process to the child process when using `fork`. This seems to mean that file descriptors can be shared with the child process even though memory cannot be shared. This could mean one can send "rich" objects that contain fd numbers as long as the other state can be serialised. Also advanced serialisation is another feature it has but I haven't explored it. – CMCDragonkai Nov 29 '21 at 05:00
  • @CMCDragonkai - If the child process is a nodejs process, there are ways to share file handles/sockets. The cluster module does something like that, for example. You can always send copies of rich objects between processes - you just have to serialize the data (often to JSON) first. I'm not sure what this has to do with this particular question though. – jfriend00 Nov 29 '21 at 05:04
  • Yea I tried it, rich objects like sockets and servers, but not my custom rich objects which contain its own fd. – CMCDragonkai Nov 30 '21 at 07:50
  • @CMCDragonkai - Yes, that is the case. You can't embed an fd in an object and share the overall object, expecting the fd to be included. Is your question answered now or is there more? – jfriend00 Nov 30 '21 at 21:56