How to capture response from child process in nodejs - node.js

I am trying to capture some response from my child process in master process. I can log information of child process in master process but unable to capture some return xyz response .
Here is code for master process:
var express = require('express');
var app = express();
const
fs = require('fs'),
cp = require('child_process');
app.get('/',onRequest );
function onRequest(request, response) {
var express = require('express');
var app = express();
var child= cp.spawn('node' ,['./child_process/block.js'],filestreamCallback);
child.stdout.on('data', function(data) {
console.log('stdout: ==== ' + data);
});
child.stderr.on('data', function(data) {
console.log('stdout: ' + data);
});
child.on('close', function(code) {
console.log('closing code: ' + code);
});
function filestreamCallback() {
response.writeHead(200, {'Content-Type': 'text/plain'});
baflog.info("Reading Stream completed");
response.write('Thanks for Your patience!\n');
response.end();
}
}
app.listen(5000);
console.log('Server started');
Child process : block.js
/*Keep waiting for 10 seconds*/
console.log("Waiting for child Process (block.js) to complete......");
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + 10000);
ret_resp();
var response = {status:'success'};
function ret_resp(){
return response;
}
console.log("Thank You for waiting......");
Like in console i see output as :
stdout====: Waiting for child Process (block.js) to complete......
-punws-sohan
stdout: ==== Thank You for waiting......
I cannot see output for return response statement
Can anyone suggest how to capture response from child process?

First of all, the busy loop uses up unnecessary CPU time. Just use a setTimeout() instead. Example:
setTimeout(function() {
ret_resp();
// ...
}, 10000);
Secondly, you can't expect return to magically write the returned value to the parent process. Try this instead:
// parent.js
var child = cp.fork('./child_process/block.js', [], { silent: true });
child.stdout.on('data', function(data) {
console.log('stdout: ==== ' + data);
});
child.stderr.on('data', function(data) {
console.log('stdout: ' + data);
});
child.on('message', function(msg) {
console.log('message from child: ' + require('util').inspect(msg));
});
child.on('close', function(code) {
console.log('closing code: ' + code);
});
// child.js
console.log('Waiting for child Process (block.js) to complete......');
setTimeout(function() {
var response = {status:'success'};
function ret_resp() {
process.send(response);
}
ret_resp();
console.log('Thank You for waiting......');
}, 10000);

Related

How to get fd of child.stdin?

How to get fd of child.stdin to do fs.writeSync/readSync? 'open' never gets fired.
const { spawn } = require('child_process');
const child = spawn('cat');
const cmd = 'foo\n';
let buff = new Buffer.from(cmd);
// child.stdin.fd is undefined
child.stdin.write(buff);
// never gets called
child.stdin.on('open', function (fd) {
fs.writeSync(fd, buff, 0, buff.length, null, err => {
if (err) throw 'Could not send command: ' + err;
console.log('Command succesfully sent');
});
});
child.stdout.on('data', (chunk) => {
// echo
process.stdout.write(chunk.toString());
});
child.on('close', (code) => {
console.log(`exited with code ${code}`);
});
The fd of child.stdin can be accessed via child.stdin._handle.fd. Not sure if this is recommended but I tested it in both v0.12.10 and v10.16.0.

How to catch error while using fork child process in node?

I am using the fork method to spawn a child process in my electron app, my code looks like this
'use strict'
const fixPath = require('fix-path');
let func = () => {
fixPath();
const child = childProcess.fork('node /src/script.js --someFlags',
{
detached: true,
stdio: 'ignore',
}
});
child.on('error', (err) => {
console.log("\n\t\tERROR: spawn failed! (" + err + ")");
});
child.stderr.on('data', function(data) {
console.log('stdout: ' +data);
});
child.on('exit', (code, signal) => {
console.log(code);
console.log(signal);
});
child.unref();
But my child process exits immediately with exit code 1 and signal, Is there a way I can catch this error? When I use childprocess.exec method I can catch using stdout.on('error'... Is there a similar thing for fork method? If not any suggestions on how I can work around this?
Setting the option 'silent:true' and then using event handlers stderr.on() we can catch the error if any. Please check the sample code below:
let func = () => {
const child = childProcess.fork(path, args,
{
silent: true,
detached: true,
stdio: 'ignore',
}
});
child.on('error', (err) => {
console.log("\n\t\tERROR: spawn failed! (" + err + ")");
});
child.stderr.on('data', function(data) {
console.log('stdout: ' +data);
});
child.on('exit', (code, signal) => {
console.log(code);
console.log(signal);
});
child.unref();

run a few node.js web servers from within a node.js application

I would like to control a few web sites using a UI to start and stop them, changing the ports that the different web server's listen to.
PM2 is a command line utility to manage node sites, but does not have a user interface that I can supply my customer.
How can I run a node.js web site from within another node.js web application.
The following node.js code does not seem to do the work.
const { exec } = require('child_process');
....
exec('node app.js', (err, stdout, stderr) => {
if (err) {
console.log(`err: ${err}`);
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
note: regular linux commands instead of the 'node app.js' command work as expected.
Got the following code to work in case you want to run the same:
This is the code on the server that will spawn a new web server.
app.get('/start', ( req, res ) => {
var node = spawn('node', ['app.js &'], { shell: true });
node.stdout.on('data', function (data) {
console.log('stdout: ' + data.toString());
});
node.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
node.on('exit', function (code) {
console.log('child process exited with code ' +
code.toString());
});
// Notify client
res.status(200).send( {} );
});
The simplest alternative would be to keep a collection of ExpressJS instances and create/destroy them as needed within NodeJS:
const express = require("express");
var app1 = express();
app1.use("/", function(req, res){ res.send("APP 1"); });
var app2 = express();
app2.use("/", function(req, res){ res.send("APP 2"); });
// start them
var server1 = app.listen(9001);
var server2 = app.listen(9002);
// close the first one
server1.close();
// port 9001 is closed
// port 9002 is still listening
However, if you need to spawn independent processess, you could have:
const { spawn } = require("child_process");
// Prevent Ctrl+C from killing the parent process before the children exit
process.on("SIGINT", () => {
console.log("Terminating the process...");
if (runningProcesses > 0) {
setTimeout(() => process.exit(), 3000);
} else {
process.exit();
}
});
function asyncSpawn(command, parameters = []) {
return new Promise((resolve, reject) => {
runningProcesses++;
console.log(command, ...parameters, "\n");
spawn(command, parameters, {
stdio: "inherit"
})
.on("close", code => {
if (code)
reject(new Error(command + " process exited with code " + code));
else resolve();
})
.on("exit", error => {
runningProcesses--;
if (error) reject(error);
else resolve();
});
});
}
And launch new processes like this:
asyncSpawn("node", ["server.js", "--param1"])
.then(() => console.log("DONE"))
.catch(err => console.error(err));

Execute parse develop command on nodejs

I'm using Parse as backend but their log system is hard to read. So I tried to execute the command "parse develop " inside a nodejs script to make what they log more readable but I can't make it work.
// var spawn = require('child_process').spawn;
var exec = require('child_process').exec;
var child = exec('parse', ['develop', 'MyApp']);
child.stdout.on('data', function (data) {
console.log('This is never called');
});
child.stderr.on('data', function (data) {
console.log('This works');
});
Is there anything I am missing?
Thanks in advance.
You should use spawn instance of exec
var spawn = require('child_process').spawn,
parse = spawn('parse-develop',['MyApp']);
parse.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
parse.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
parse.on('close', function (code) {
console.log('child process exited with code ' + code);
});

how to send message to parent process

Can I send message to parent process?
master
var child =child_process.fork();
child.send({msg:msg})
child process
process.on('message', function(){
});
// how to send message to parent??
In short use: process.send()
Longer example, I wrote awhile ago named forktest.js:
var cp = require('child_process');
if (!process.send) {
var p = cp.fork(__dirname + '/forktest');
p.send({
count: 10
});
p.on('message', function(data) {
process.exit(0);
});
} else {
process.on('message', function(data) {
console.log(data);
data.count--;
if (data.count === 0) {
process.send({});
process.exit(0);
}
var p = cp.fork(__dirname + '/forktest');
p.send(data);
p.on('message', function(data) {
process.send(data);
process.exit(0);
});
});
}

Resources