javascriptnode.jsrabbitmqforever

How to keep forked child process alive in node js


I want to create a rabbitmq cli running like foreverjs with node. It can spawn child_process and keep it running in the background and can communicate with child_process at any time. The problem I am facing is when main cli program exit the child_process seems to stop running as well, I tried to fork with detached:true and .unref() it doesn't work. How do i run a child process in the background even after the parent caller process exited?

cli.js - parent

const { fork, spawn } = require('child_process');
const options = {
  stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
  slient:true,
  detached:true
};

child = fork('./rabbit.js', [], options)

child.on('message', message => {
  console.log('message from child:', message);
  child.send('Hi');
  // exit parent
  process.exit(0);
});

child.unref()

rabbit.js - child if it is up and running, 'i' should keep incrementing

var i=0;
i++;
if (process.send) {
  process.send("Hello"+i);
}

process.on('message', message => {
  console.log('message from parent:', message);
});

Solution

  • I think fork doesn't have a detached option. Refer node docs for fork.

    If you use spawn, the child keeps running even if the parent exits. I have modified your code a bit to use spawn.

    cli.js

    const { fork, spawn } = require('child_process');
    const options = {
      slient:true,
      detached:true,
        stdio: [null, null, null, 'ipc']
    };
    
    child = spawn('node', ['rabbit.js'], options);
    child.on('message', (data) => {
        console.log(data);
        child.unref();
        process.exit(0);
    });
    

    rabbit.js

    var i=0;
    i++;
    process.send(i);
    // this can be a http server or a connection to rabbitmq queue. Using setInterval for simplicity
    setInterval(() => {
        console.log('yash');
    }, 1000);
    

    I think when you use fork, an IPC channel is established between the parent and the child process. You could try disconnecting the IPC channel gracefully before exiting the parent process. I'll try it out and update the answer if it works.

    Update:

    I have updated cli.js and rabbit.js to get it working as asked. The trick is to use ipc file descriptor in stdio options. That way you can communicate with the parent from the child. The first three fds will be the default values if marked as null. For more info, refer stdio options docs