Hi I am using child_process.spwan to start a child process running a python script on Windows. The script listens on SIGINT to gracefully exits itself. But Windows does not support signals and all node did was simulating. So child_process.kill('SIGINT')
on Windows is actually killing the process unconditionally (no graceful exit, python's SIGTERM/SIGINT handler not called). Also writing a ctrl+c
character to stdin does not work either.
When I look into Python APIs, I got the CTRL_BREAK_EVENT and CTRL_C_EVENT that can serve the need. I am wondering if node has equivalent platform-specific APIs like these?
Related posts but not working ones: How to send control C node.js and child_processes sending crtl+c to a node.js spawned childprocess using stdin.write()?
Usually, Node. js allows single-threaded, non-blocking performance but running a single thread in a CPU cannot handle increasing workload hence the child_process module can be used to spawn child processes. The child processes communicate with each other using a built-in messaging system.
Node provides child_process module which provides ways to create child process.
You can use IPC messages to signal to the child that its time to stop and gracefully terminate. The below approach uses process.on('message')
to listen for messages from the parent in the child process & child_process.send()
to send messages from the parent to the child.
The below code has a 1 minute timeout set to exit if the child hangs or is taking to long to finish.
py-script-wrapper.js
// Handle messages sent from the Parent
process.on('message', (msg) => {
if (msg.action === 'STOP') {
// Execute Graceful Termination code
process.exit(0); // Exit Process with no Errors
}
});
Parent Process
const cp = require('child_process');
const py = cp.fork('./py-script-wrapper.js');
// On 'SIGINT'
process.on('SIGINT', () => {
// Send a message to the python script
py.send({ action: 'STOP' });
// Now that the child process has gracefully terminated
// exit parent process without error
py.on('exit', (code, signal) => {
process.exit(0);
});
// If the child took too long to exit
// Kill the child, and exit with a failure code
setTimeout(60000, () => {
py.kill();
process.exit(1);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With