Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why parent process doesn't exit automatically after running a detached child?

Node.js 8.9.1, Linux version 4.10.0-42-generic

Parent

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

const forked = fork('child.js', {
  detached: true,
  stdio: 'ignore'
});

const config = {
  name: 'trex',
  interval: 2000
};

forked.send(config);
forked.unref();

for (let i = 0; i < 3; i++) {
  console.log('do staff');
}

Child

const work = function() {
  let sum = 0;
  for (let i = 0; i < 1e10; i++) {
    sum += i;
  }
};

const start = function(config) {
  setTimeout(function run() {
    work();
    setTimeout(run, config.interval);
  }, config.interval);
};

process.on('message', function(config) {
  start(config);
});

I need the parent to start the child and exit normally. Now if I execute node parent.js I see the parent still running.

trex@beast-cave:~/dev/$ ps aux | grep -e "parent\|child" | grep node
trex      5134  0.0  0.1 874016 29460 pts/11   Sl+  10:44   0:00 node parent.js
trex      5140 86.3  0.1 874108 30252 ?        Rsl  10:44   4:59 /home/trex/.nvm/versions/node/v8.9.1/bin/node child.js

I know there is process.exit(). But why it doesn't exit normally? In my app parent is inside the setTimeout loop, there is a lot of logic and it must be run only once in an interval of time.

like image 464
srgbnd Avatar asked Nov 02 '25 18:11

srgbnd


1 Answers

From https://nodejs.org/api/child_process.html documentation:

subprocess.disconnect()# Added in: v0.7.2 Closes the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. After calling this method the subprocess.connected and process.connected properties in both the parent and child (respectively) will be set to false, and it will be no longer possible to pass messages between the processes.

The 'disconnect' event will be emitted when there are no messages in the process of being received. This will most often be triggered immediately after calling subprocess.disconnect().

Note that when the child process is a Node.js instance (e.g. spawned using child_process.fork()), the process.disconnect() method can be invoked within the child process to close the IPC channel as well.

const work = function() {
  let sum = 0;
  for (let i = 0; i < 1e10; i++) {
    sum += i;
  }
};

const start = function(config) {
  setTimeout(function run() {
    work();
    setTimeout(run, config.interval);
  }, config.interval);
};

process.on('message', function(config) {
  start(config);
  process.disconnect();
});
like image 185
Sergio Scarnatto Avatar answered Nov 04 '25 09:11

Sergio Scarnatto