Not a duplicate of this : I can kill process fine, I want to know how to detect, within the process, that it's being killed, and gracefully shutdown.
I have a CLI tool to spawn and kill a child node.js process. The demo code is contained in these three files:
spawn.js
-- Will spawn the child.js
script, detached. For simplicity, I pipe the child's stdio
to an out.log
file
child.js
-- A simple counter which writes to a file, uses the readline
method to detect an emulated SIGINT in Windows
kill.js
-- Invokes a process.kill()
on the child process, using it's PID
spawn.js
'use strict';
var spawn = require('child_process').spawn;
var fs = require('fs');
var path = require('path');
var childFilePath = path.resolve(__dirname, 'child.js');
var out = fs.openSync('./out.log', 'a');
var err = fs.openSync('./out.log', 'a');
var options = {
detached: true,
stdio: ['ignore', out, err],
};
var child = spawn(process.execPath, [childFilePath], options);
child.unref();
child.js
'use strict';
var fs = require('fs');
var path = require('path');
if (process.platform === 'win32') {
console.log('win32 true');
var rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on('SIGINT', function() {
process.emit('SIGINT');
});
}
process.on('SIGINT', function() {
console.log('SIGINT');
process.exit();
});
var filepath = path.resolve(__dirname, 'pid.txt');
fs.writeFile(filepath, process.pid);
var i = 0;
setInterval(function () {
console.log(i++);
}, 1000);
kill.js
'use strict';
var fs = require('fs');
var path = require('path');
var pidPath = path.resolve(__dirname, 'pid.txt');
fs.readFile(pidPath, 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
process.kill(data, 'SIGINT');
});
When sending the process.kill(PID, 'SIGINT')
, it doesn't actually detect it as a SIGINT
in windows. I can run child.js
manually and use CTRL+C
to kill the process to trigger a SIGINT
, so I know that the readline
code is working (or maybe not since SIGINT
will trigger without the readline
code, but it will n.netheless trigger a SIGINT
)
Does process.kill()
not send the type of signal to a detached process? How do I detect that that a separate script is trying to kill my child process and shutdown gracefully?
I have exactly the same problem. I noticed the rl.on("SIGINT")
is not working but rl.on("close")
works!
var rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
})
rl.on('close', function() {
process.emit('SIGINT')
})
Here is my debug output
Sat Feb 17 2018 11:43:28 GMT+0800 (China Standard Time) process started (pid=6920)
Sat Feb 17 2018 11:43:28 GMT+0800 (China Standard Time) SIGINT captured! cleanup and then call process.exit(0)
Sat Feb 17 2018 11:43:28 GMT+0800 (China Standard Time) byebye! (code=0, signal=undefined)
Note that I'm not pretty sure that adding extra code to a subprocess is a good idea. Think about forking a non nodejs process, it might not be able to use such trick (eg redis-server, kdb+). I am still looking for a way to let spawn.js
to kill subprocess gracefully.
Update 1: Here is my initial problem reported to PM2 community https://github.com/Unitech/pm2/issues/3467
There is a library kill-with-style to do this and works with detached process too. It has various options to set signal, timeout and retry options.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.