Reputation: 371
I have a architecture with one parent that spawns tow childs (one in c++ the other in python). The parent spawns with the following class :
export class subProcess {
protected cmd: string;
protected args: string[];
protected process: child.ChildProcess;
constructor(cmd: string, args: string[]) {
this.cmd = cmd;
this.args = args;
this.process = null;
}
spawn(): void {
this.process = child.spawn(this.cmd, this.args);
const rlout = readline.createInterface({
input: this.process.stdout,
});
rlout.on('line', line => this.logger.info(line));
const rlerr = readline.createInterface({
input: this.process.stderr,
});
rlerr.on('line', line => this.logger.error(line));
this.process.on('exit', (code: number) => {
this.logger.info(`exit code: ${code}`);
});
}
When I interrupt the parent whith a Ctrl-C, signal SIGINT
is caugth in the parent process to be able to first disconnect and kill the childs gracefully :
process.on('SIGINT', () => {
this.bus.disconnect();
});
disconnect
is a function that sends an "exit_process"
command to the childs via ZeroMQ. This command works perfectly fine in normal behavior. But the problem is that when I press Ctrl-C, the SIGINT
is caugth by the Parent and it executes disconnect
function (as expected) but it seems that it also propagate SIGINT
to the childs. Indeed, the "exit_process"
command sent via ZeroMQ reaches it's timeout (which means that the childs have never received/answered) whereas the childs emit a returned code via the exit
event.
The point is that I can't detache and/or unref the childs, or manage signals in childs, for project reasons. And I expected the parent to catch the SIGINT
whithout propagating it to the childs.
One more point, I tried to add the following in subProcess
class, but it did not work :
this.process.on('SIGINT', () => {
console.log('SIGINT received. Do nothing');
});
Upvotes: 1
Views: 227
Reputation: 42458
Your SIGINT
is being passed to the entire process group — see this section on Wikipedia. However, you're probably not seeing any output because of how the child process pipes are established.
When spawning a new child process, you can provide stdio
options:
this.process = child.spawn(this.cmd, this.args, {stdio: 'inherit'});
The above causes the parent's process.stdin
, process.stdout
, process.stderr
to be inherited by the child process. If you use this approach, you will see that your child is receiving the SIGINT
.
The default behaviour is to create separate streams, which is why you are not seeing your console.log
. You could also listen to the child's stdout stream:
this.process.stdout.on('data', data => console.log(data.toString()));
Upvotes: 1