how to send message to parent process - node.js

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);
});
});
}

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.

Dequeue request in Azure Service Bus when queue length < 10 frequently returns null

I have been experimenting with Azure Service Bus queues in NodeJS. I have built the sender.js and listener.js based on their code sample in the documentation. Building a queue works fine. Dequeuing and deleting messages from the queue works fine until message length reaches 10. At this point, dequeue requests return null messages around 4 out of 5 times. If I keep looping the dequeue requests, eventually, it will dequeue and delete those last 10 messages. But, this seems highly inefficient. Has anyone else experience this problem?
listener.js
var azure = require('azure');
var async = require("async");
var connectionString = process.env.CONNECTION_STRING || "Endpoint=sb://endpoint"; // dev
console.log(process.env.CONNECTION_STRING);
var serviceBusService = azure.createServiceBusService(connectionString);
// var serviceBusService = azure.createServiceBusService();
exports.createQueue = function (req,res) {
var body = req.body;
serviceBusService.createQueueIfNotExists(body.queueName, function(error){
console.log(error);
if(!error){
// Queue exists
return res.send(200);
} else {
return res.send(500, error);
}
});
};
exports.sendMessageToQueue = function (req, res) {
var body = req.body;
var message = {
body: 'Test message',
customProperties: {
testproperty: 'TestValue'
}};
serviceBusService.sendQueueMessage(body.queueName, message, function(error){
if(!error){
// message sent
return res.send(200);
} else {
return res.send(500, error);
}
});
}
exports.receiveMessageFromQueue = function (req, res) {
var body = req.body;
serviceBusService.receiveQueueMessage(body.queueName, function(error, receivedMessage){
if(!error){
console.log(receivedMessage);
// Message received and deleted
return res.send(200,receivedMessage);
} else {
return res.send(500, error);
}
});
}
function _receiveMessageFromQueue(queueName,delayTimeIfQueueIsEmpty,callback) {
serviceBusService.receiveQueueMessage(queueName, function(error, receivedMessage){
console.log(error, receivedMessage);
// console.log(error);
if (error == 'No messages to receive') {
// call the rest of the code and have it execute after 30 seconds
setTimeout(function() {
callback(receivedMessage);
}, delayTimeIfQueueIsEmpty);
} else {
// callback immediately
callback(receivedMessage);
}
});
}
function _sendQueueMessage(queueName,message,callback) {
serviceBusService.sendQueueMessage(queueName, message, function(error){
console.log(error);
callback();
});
}
function listenMessageQueue(concurrency,delayTimeIfQueueIsEmpty,queueName) {
var taskHandler = function(task, done) {
_receiveMessageFromQueue(task.queueName, delayTimeIfQueueIsEmpty, function(message) {
if (message) {
console.log('hello ' + message.body);
}
myQueue.push({ id: task.id + 1, queueName: queueName, url: "http://localhost/get-person/" + task.id + 1});
done();
});
};
var queueSize = concurrency;
var myQueue = async.queue(taskHandler, queueSize);
myQueue.drain = function() {
console.log("All the work has been done.");
}
for(var i = 0; i < concurrency; i++) {
myQueue.push({ id: i, queueName: queueName, url: "http://localhost/get-person/"+i });
}
}
delayTimeIfQueueIsEmpty = 30000; // 30s
concurrency = 2;
queueName = "jobs";
// listen and dequeue message from azure message bus
listenMessageQueue(concurrency,delayTimeIfQueueIsEmpty,queueName);
sender.js
var azure = require('azure');
var async = require("async");
var connectionString = process.env.CONNECTION_STRING || "Endpoint=sb://endpoint";
console.log(process.env.CONNECTION_STRING);
var serviceBusService = azure.createServiceBusService(connectionString);
exports.createQueue = function (req,res) {
var body = req.body;
serviceBusService.createQueueIfNotExists(body.queueName, function(error){
console.log(error);
if(!error){
// Queue exists
return res.send(200);
} else {
return res.send(500, error);
}
});
};
exports.sendMessageToQueue = function (req, res) {
var body = req.body;
var message = {
body: 'Test message',
customProperties: {
testproperty: 'TestValue'
}};
serviceBusService.sendQueueMessage(body.queueName, message, function(error){
if(!error){
// message sent
return res.send(200);
} else {
return res.send(500, error);
}
});
}
exports.receiveMessageFromQueue = function (req, res) {
var body = req.body;
serviceBusService.receiveQueueMessage(body.queueName, function(error, receivedMessage){
if(!error){
console.log(receivedMessage);
// Message received and deleted
return res.send(200,receivedMessage);
} else {
return res.send(500, error);
}
});
}
function _receiveMessageFromQueue(queueName,delayTimeIfQueueIsEmpty,callback) {
serviceBusService.receiveQueueMessage(queueName, function(error, receivedMessage){
console.log(error, receivedMessage);
// console.log(error);
if (error == 'No messages to receive') {
// call the rest of the code and have it execute after 30 seconds
setTimeout(function() {
callback(receivedMessage);
}, delayTimeIfQueueIsEmpty);
} else {
// callback immediately
callback(receivedMessage);
}
});
}
function _sendQueueMessage(queueName,message,callback) {
serviceBusService.sendQueueMessage(queueName, message, function(error){
console.log(error);
callback();
});
}
function listenMessageQueue(concurrency,delayTimeIfQueueIsEmpty,queueName) {
var taskHandler = function(task, done) {
_receiveMessageFromQueue(task.queueName, delayTimeIfQueueIsEmpty, function(message) {
if (message) {
console.log('hello ' + message.body);
}
myQueue.push({ id: task.id + 1, queueName: queueName, url: "http://localhost/get-person/" + task.id + 1});
done();
});
};
var queueSize = concurrency;
var myQueue = async.queue(taskHandler, queueSize);
myQueue.drain = function() {
console.log("All the work has been done.");
}
for(var i = 0; i < concurrency; i++) {
myQueue.push({ id: i, queueName: queueName, url: "http://localhost/get-person/"+i });
}
}
function pushMessageQueue(concurrency,queueName) {
var taskHandler = function(task, done) {
var message = {
body: String(task.id),
customProperties: {
url: task.url
}};
_sendQueueMessage(task.queueName, message, function() {
console.log('hello ' + task.id);
myQueue.push({ id: task.id + 1, queueName: queueName, url: "http://localhost/get-person/" + task.id + 1});
done();
});
};
var queueSize = concurrency;
var myQueue = async.queue(taskHandler, queueSize);
myQueue.drain = function() {
console.log("All the work has been done.");
}
for(var i = 0; i < concurrency; i++) {
myQueue.push({ id: i, queueName: queueName, url: "http://localhost/get-person/"+i });
}
}
concurrency = 2;
queueName = "jobs";
pushMessageQueue(concurrency,queueName); // push message to queue for testing: 100 messages per call
finally was able to get through to Azure support and found the answer. ServiceBus by default enables partitioning. When making http requests (the NodeJS SDK for Azure ServiceBus makes http REST calls), when message count is low can result in a partitions with different sets of messages, as they have not had a chance to sync. This is resolved by creating a new Queue that disables partitioning or by increasing the keep alive or by using the DotNet SDK which allows https requests to be made.

How to make a gulp stream synchronous

plugin.js
module.exports = function(holder) {
return through.obj(function(file, encoding, callback) {
console.log('2')
return callback(null, file);
}
}
task
gulp.task('t', function() {
console.log('1');
var tmp = gulp.src(...).pipe(require('plugin')())
console.log('3');
return tmp;
});
The console result is:
1
3
2
But what I want is:
1
2
3
How could I do that?
You don't make the stream synchronous. Instead you listen for the end event :
gulp.task('t', function() {
console.log('1');
return gulp.src(...)
.pipe(require('plugin')())
.on('end', function() {
console.log('3');
});
});

How to capture response from child process in nodejs

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);

Return value, or stop script

Helo,
i create API in Windows Azure Mobile service, In this api script i have function to connect the other service. I have problem how to return value or stop executable my script when i have good answer from service. Function process.exit(1), don't work.
function function1(item,response) {
var buf ='';
var net = require('net');
var HOST = 'xxxx.xxxx.xxxx.xxxx';
var PORT = xxx;
var client = new net.Socket();
client.setTimeout(100000, function() {
console.log("Timeout");
response.send(500, "Timeout");
});
client.connect(PORT, HOST, function() {
client.write(item + "\n");
client.on('data', function(data) {
buf = buf + data.toString('utf-8');
});
client.on('close', function() {
});
client.on('end', function() {
if (buf.length > 1) {
var result = JSON.parse(buf);
//if resulr.Aviable is true the functios should return result or send result and stop execiuting script
if ( result.Avaiable) {
response.send(200, result);
//now i wont't to respond answer to client or return my value(result)
console.log('Send data');
}
}
client.destroy();
});
});
}
One alternative is to have a flag which indicates whether a response has been sent or not. This way, when the first of the alternatives is reached, you can set the flag to true (possibly clearing the timeout so it doesn't linger more than it needs) and in all cases check whether the flag has been set before returning the response. Something along the lines of the code below:
function function1(item,response) {
var buf = '';
var net = require('net');
var HOST = 'xxxx.xxxx.xxxx.xxxx';
var PORT = xxx;
var client = new net.Socket();
var responseSent = false;
var timeoutHandler = client.setTimeout(100000, function() {
if (!responseSent) {
responseSent = true;
console.log("Timeout");
response.send(500, { error: "Timeout" });
}
});
client.connect(PORT, HOST, function() {
client.write(item + "\n");
client.on('data', function(data) {
buf = buf + data.toString('utf-8');
});
client.on('close', function(had_error) {
if (!responseSent) {
clearTimeout(timeoutHandler);
responseSent = true;
console.log('Socket closed');
response.send(500, { error: had_error ? 'Socket error' : 'unknown' });
}
});
client.on('end', function() {
if (!responseSent) {
responseSent = true;
clearTimeout(timeoutHandler);
if (buf.length > 1) {
try {
var result = JSON.parse(buf);
if (result.Available) {
response.send(200, result);
} else {
response.send(500, { error: 'Socket data is not available' });
}
} catch (ex) {
response.send(500, { error: 'error parsing JSON', exception: ex });
}
} else {
// We should always return a response
response.send(500, { error: 'No data read from socket' });
}
}
client.destroy();
});
});
}
Notice that since node.js runs on a single thread, you can assume that there will be no cases where the response is sent twice. Also, you should make sure that the response is always sent once - in the code you had, if there was a socket error, or if buf.length was not greater than 1, or if result.Avaiable was not true, then the timeout response would be sent, but you didn't need to wait for the whole (100 seconds) time to send that response.

Resources