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);
});
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 fd
s will be the default values if marked as null
. For more info, refer stdio options docs