How to kill Node Express child process? - node.js

Inside one Node/Express server, I started another Node/Express server as child process:
let appifi = child.spawn('node', [babel_path, www_path], {
cwd: appifi_path,
env: appifi_env,
})
This worked fine and appifi got a pid, say 2376.
When trying to stop the child process, appifi.kill() will kill the process with pid 2376, but there is a respawned server process running, usually with a pid equals to it's parent's pid plus 5 (I don't know if this is a strict rule).
My question is, how to kill them both in parent server? is it safe to process.kill(appifi.pid + 5)? or there are any better ways?

You can kill both (actually, ALL) node servers by killall -9 node

Related

Linux process automatically starts again with new new PID after killing

I wanna stop Node server on linux but when I try to stop it, It automatically starts with new PID how can I stop this completely. Here you can see I tried to stop Nginx and Node.
How can I check if it is a linux zombie process? If yes then How can I kill it? otherwise
I have tried tried these commands.
kill pid
Kill -9 pid
killall node <<command not working
This was spawn by it's parent process, I search out parent process after killing that this stop as well.

Node child process doesn't release port, even after it's killed by parent

I have a parent node process and a child node process. The child binds a web server to port 5000. The parent sometimes kills and restarts the child (usually because a file has changed).
The problem is: when the second child process starts, I get Error: listen EADDRINUSE :::5000.
The weird thing is, I kill the child process with child.kill(), then I wait for it to fire a close event, and then I wait 5 seconds with setTimeout, before trying to start a new child process...yet it always complains that the port is occupied. But if I manually kill the parent process (ctrl+C in my terminal) and run it again, I don't get the error. So killing the parent seems to be the only way to successfully release the port.
Can anyone think of a reason why this would happen? Why does the port remain occupied after the process that bound it is killed, until its parent process stops?
Actually it block the process so you need to kill the process by following command just type
ps -ax
You will get list of processes from where you need to check the process id which is been blocked then kill the process by this command
kill -9 processId
Kill all your running port by below command.
pkill node

How to kill Respawning Node

Need help for killing process node JS.
I'm trying to stop node js process on my server,
I've been use
killall -9 node
and here is the response
node(30332): Operation not permitted
node: no process found
So I used
sudo killall -9 node
but the node js is still respawning with different PID. Any help?
Finally found the problems, there are Parents ID that related to Node Process.
I'm using
ps -ef | grep no
and found the Parent Process ID / Sleep Process and kill the parents and then kill the node process.
You can use process.kill() or process.exit() to kill/stop node process internally when there is stop request.
To stop all node process from command line use pkill node(in linux).

Can't kill child process on Windows

The following will never exit
var child_process = require('child_process');
var ps = child_process.spawn('.\\node_modules\\.bin\\babel.cmd', ['input.js', '--out-file', 'output.js', '--watch']);
ps.on('exit', function() {
console.log('exit');
});
ps.on('close', function() {
console.log('close');
});
setTimeout(function () {
ps.kill();
}, 2000);
What's going on here? also what is the correct thing to do here? The only way to make this process actually close is to kill the parent process. I suspect it's waiting for stdio to flush or something like that?
It does die if it is given an 'ignore' stdio configuration, but I need the streams.
var ps = child_process.spawn('.\\node_modules\\.bin\\babel.cmd', ['test.js', '--out-file', 'output.js', '--watch'], {
stdio: 'ignore'
});
You are spawning child process cmd.exe by using babel.cmd. This process then starts another grandchild process node and runs babel script. When you do ps.kill() it only kills the cmd.exe but not the child processes created by it.
Although cmd.exe is closed, the stdio stream of the parent process is still shared with the other processes in the tree. So the parent process is waiting for the stream to be closed. Using stdio: 'ignore' will only stop sharing the stdio stream with other processes in the tree but those grandchild processes will still continue running.
Update:
After discussing with OP, I tested with all three stdio options: pipe(default), inherit, ignore in iojs 3.3.0, Windows 7 (32bit). None of them kills the grandchild process.
With inherit and ignore, both parent process and child process(cmd.exe) are killed but the grand child process still floats around and doesn't belong to any process tree.
With pipe, only the child process is terminated but both parent and grand child process continue running. The reason that parent process is not exiting is most likely because the stdio of parent node.exe is still shared with the other processes as mentioned in original answer.
child.unref() doesn't have any effect on killing grand child process. It only removes the child process from parent's event loop so that the parent process can exit normally.
I could think of couple of solutions:
Invoke the babel.js directly without that cmd script:
var ps = child_process.spawn('node', ['.\\node_modules\\babel\\bin\\babel.js', 'input.js', '--out-file', 'output.js', '--watch'])
Use windows taskkill command with \T flag to kill the process and all the child processes started by it:
os = require('os');
if(os.platform() === 'win32'){
child_process.exec('taskkill /pid ' + ps.pid + ' /T /F')
}else{
ps.kill();
}
There are some npm modules that can handle killing child processes in both Unix and Windows e.g. tree-kill. For windows it uses taskkill or tasklist.
I have the same issue on Windows (Win 10 64x). I can't terminate a process of a spawned child process.
I start a service (custom HTTP server service.windows) using child_process.spawn():
const { spawn } = require('child_process');
let cp = spawn('"C:\\Users\\user\\app\\service.windows"', [], { shell: true, });
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
console.log('cp.connected', cp.connected);
console.log('process.pid', process.pid); // 6632 <<= main node.js PID
console.log('cp.pid', cp.pid); // 9424 <<= child PID
// All these are useless, they just kill `cp`
cp.kill('SIGINT'); // Doesn't terminate service.windows
cp.kill('SIGKILL'); // Doesn't terminate service.windows
cp.kill('SIGTERM'); // Doesn't terminate service.windows
});
And I want to terminate my HTTP server service (service.windows). And it is not possible on Windows using cp.kill('ANY SIGNAL'). Node.js kills its child process (cp) but my HTTP server (service.windows) still runs fine.
When I check it in other terminal, I see my server is running just fine:
$ netstat -ano | findstr :9090
TCP 0.0.0.0:9090 0.0.0.0:0 LISTENING 1340
TCP [::]:9090 [::]:0 LISTENING 1340
I try manually kill my server by PID but with T flag, not F. The difference:
T terminate all child processes along with the parent process, commonly known as a tree kill.
F process(es) be forcefully terminated.
$ taskkill -T -PID 1340
ERROR: The process with PID 1340 (child process of PID 9424) could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
And it exactly says that my server 1340 is a child of that cp - PID 9424.
OK, I try to terminate that cp using T flag again. And boom, not possible. cp is a child of my main node.js process.pid 6632:
$ taskkill -T -PID 9424
ERROR: The process with PID 1340 (child process of PID 9424) could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
ERROR: The process with PID 9424 (child process of PID 6632) could not be terminated.
Reason: One or more child processes of this process were still running.
I can only kill it forcefully with F flag:
$ taskkill -F -T -PID 9424
SUCCESS: The process with PID 1340 (child process of PID 9424) has been terminated.
SUCCESS: The process with PID 9424 (child process of PID 6632) has been terminated.
Most disappointing thing is that Node.js docs doesn't say jack ship about how to deal with this issue. They only say "yes, we know the issue exist and we just inform you about it".
The only option I see on Windows is to use taskkill -F -T -PID 9424 in spawned process:
exec('taskkill -F -T -PID 9424');
One potential solution is to call ReadableStream.end or ReadableStream.destroy
The most straight forward solution, don't spawn scripts instead spawn node directly.
For unix, the script is the npm executable. For windows however we need to resolve the name from the .cmd file.
if (path.extname(command).toLowerCase() == '.cmd') {
var content = '' + fs.readFileSync(command);
var link = (/node "%~dp0\\(.*?)"/.exec(content) || [])[1];
if (link) {
command = path.resolve(path.dirname(command), link);
}
}
var ps = child.spawn('node', [command].concat(args), options);
For me, my process was spawn of cmd.exe with the args:
/s /c start /B /I /belownormal ffmpeg.exe -hide_banner -i somevideo.mp4 -vn -ar 48000 -ac 2 -c:a pcm_s16le -f wav -
I tried most of the suggested answers, but what solved it was calling child.stdin.destroy();
child.stderr.destroy();
child.stdout.destroy();
This could be because I was explicitly using stdout to get data from the process..
I still call child.kill('SIGINT'); for good measure.
taskkill gave me 'pid not found'.
(node 12).

Run node as background process from script running as child process

I'm running a node server on port 5100. It executes a shell script as child process which in turn starts another node server.
var execFile = require('child_process').execFile;
execFile("./testscript", args, {cwd: cwd}, function (error, stdout, stderr) {
console.log("error.." + error);
console.log("stdout.." + stdout);
console.log("stderr.." + stderr);
})
In script i'm running a node process by nohup as :
nohup node server.js PORT=5200 2>/dev/null 1>/dev/null &
Now node#5200 has parentid of testscript which in turn has parentid of node#5100.
When i kill PID of node#5100 everything stops.
I want node#5200 to still run when testscript and node#5100 have exited.
You need to set the detached option when you create the child process. This is sort of like nohup. See the documentation here: http://nodejs.org/api/child_process.html#child_process_options_detached
What this does is to make the child process the leader of a new "process group," so when the parent process group dies, the child can continue running.
Edit: the documentation says:
When using the detached option to start a long-running process, the process will not stay running in the background unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal.
So you must write code like this:
var child = spawn(cmd, args, {detached: true, stdio: ['ignore', 'ignore', 'ignore']});
child.unref();
Or you can use their example to have stdout redirect to a file, etc.
When i spawned a process from a file that ran once, my child process had perfect behavior as parent file exited normally.
Issue was raised as i was spawning process by a server file that was killed by Ctrl+c so it gave an error code on exit and as a result whole process group got SIGTERM which lead to killing of child process.
To successfully implement spawning i used double spawn i.e spawned a child process from my server file that further spawned child_process that ran my other node server. So i was able to avoid SIGTERM to reach grandchild and fulfill my requirement.

Resources