How to kill child_process in node.js -- req.on close - javascript

I am trying to kill the child process when "requst.on('close' " is called. But child.pid inside this callback always points to most recent request. The question is: how can I match the child.pid to the request? Thanks
var query_script = "query.py"
var express = require('express');
var app = express();
var spawn = require('child_process').spawn;
app.get('/:version/query', function(request, response) {
child = spawn('python, ['query.py', request.originalUrl])
console.log("start pid=" + child.pid + ": " + request.originalUrl)
request.on('close', function () {
console.log("1: current pid=" + child.pid)
//child.kill('SIGTERM');
})
child.stdout.pipe(response)
});
app.listen(3000);
console.log('Listening on port 3000...');

Define child within your closure by putting var in front of it.
var child = spawn('python, ['query.py', request.originalUrl])

Related

If condition directly goes to else always in my case in node js

I am counting list of process and based on process counter trying to perform something but if condition directly goes to ELSE regardless of process counter.
My code :
var express = require('express');
var app = express();
//var sleep = require('sleep');
var counter = 0;
app.get('/', function (req, res) {
res.send(
'<form action="/server" method="POST">' +
' <input type="submit" name="server" value="Run Script" />' +
'</form>');
});
app.get('/counter', function (req, res) {
res.end("Process Counter = " + counter);
});
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./client');
counter++;
child.on("close", function () { counter --; });
if(counter > 2)
{
app.get('/m', function (req, res) {
res.end("Already multiple process running. = " + counter);
});
}
else
{
app.get('/m', function (req, res) {
res.end("Single or No process running currently = " + counter);
});
}
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("app listening at http://%s:%s", host, port)
})
I want to pause / sleep server when process counter reach 10 and then process next queue requests once previous 10 completes so trying to setting like process list of processes in slots like 10,10,10 etc. I will try to manage it once if condition work proper based on counter. Counter seems return correct count.
Few issues with your code. So I created a simple client.js
function test() {
console.log("Running test");
setTimeout(test, 10000);
}
test();
This is nothing but a infinite loop. Then I used app object for the global counter
if (!app.counter)
app.counter = 0;
Next your post becomes below
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./client');
app.counter++;
child.on("close", function () {
app.counter--;
});
res.send(200, "Current Processes - " + app.counter);
});
Also you were not ending the POST request, so I added res.send(200, "Current Processes - " + app.counter);
Next the /m endpoint is updated as below
app.get('/m', function (req, res) {
if (app.counter > 2) {
res.end("Already multiple process running. = " + app.counter);
}
else {
res.end("Single or No process running currently = " + app.counter);
}
});
So the final code is below
var express = require('express');
var app = express();
//var sleep = require('sleep');
if (!app.counter)
app.counter = 0;
app.get('/', function (req, res) {
res.send(
'<form action="/server" method="POST">' +
' <input type="submit" name="server" value="Run Script" />' +
'</form>');
});
app.get('/counter', function (req, res) {
res.end("Process Counter = " + app.counter);
});
app.get('/m', function (req, res) {
if (app.counter > 2) {
res.end("Already multiple process running. = " + app.counter);
}
else {
res.end("Single or No process running currently = " + app.counter);
}
});
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./client');
app.counter++;
child.on("close", function () {
app.counter--;
});
res.send(200, "Current Processes - " + app.counter);
});
var server = app.listen(8081, function () {
var host = server.address().address;
var port = server.address().port;
console.log("app listening at http://%s:%s", host, port)
});
If you run the server, it will work fine now
$ curl -X POST http://127.0.0.1:8081/server
Current Processes - 1
$ curl -X POST http://127.0.0.1:8081/server
Current Processes - 2
$ curl -X POST http://127.0.0.1:8081/server
Current Processes - 3
$ curl -X POST http://127.0.0.1:8081/server
Current Processes - 4
And the /m endpoint
$ curl http://127.0.0.1:8081/m
Already multiple process running. = 4
One key thing for testing this is to make sure that you don't launch the script using debugging, you run it. If you look at the child process spawnArgs you will find it as below
And our main process was started as /usr/local/bin/node --inspect-brk=54160 ..../test.js
So the fork tries to launch another process with --inspect-brk=54160, but that port is already busy with our debugger and doesn't let the child process run. So that is the reason you should run it directly instead of debugging the main code

Node.js and Socket.io in Phaser.js not connecting socket.io/?EIO=3&transport=polling

I am able to run my node.js server, my phaser.js game runs but I get no 'connected' console.log when the game runs. I instead get this error message from the client end:
enter image description here
socket.io-1.4.5.js:1 GET http://192.168.128.184:8080/socket.io/?EIO=3&transport=polling&t=LdMR6Ro net::ERR_CONNECTION_REFUSED
SERVER:
var serverPort = 8080;
console.log("Initializing Server.");
var express = require('express');
var connect = require('connect');
var app = express();
var serv = require('http').Server(app); //.createServer(app);
var io = require('socket.io').listen(serv); //(serv,{});
console.log("Starting Server.");
var serveStatic = require('serve-static');
connect().use(serveStatic(__dirname)).listen(serverPort, function(){
console.log('Server running on ' + serverPort + ' !');
});
app.get('/',function(req, res) {
res.sendFile(__dirname + '/index.html');
});
serv.listen(8081);
var SOCKET_LIST = {};
io.on('connection',function(socket){
console.log("A user is connected");
});
io.sockets.on('connection', function(socket){
console.log('Socket connection');
});
CLIENT
var local = "http://" + document.location.host + ":8081";
var socket = io().connect(local);
In your client code you are using io().connect(local) however the correct way to connect using a specified address with your variable is io.connect(local).
Also, document.location.host will include ":8080" if it is a part of the address you used to obtain the page, therefore you need to remove it. You can try something like document.location.host.split(':')[0]

Socket.IO undefiend variable

I am using socket.io to create an interactive graph app. on the server side have a graph variable. When the user loads the page a test event is sent to the server, which sets up the variable and returns it to the users. I have a second event for node dragging, but when i try to drag the node the server says that the graph's nodes and link variables are undefined.
var express = require('express'),
app = express(),
http = require('http'),
socketIo = require('socket.io');
var server = http.createServer(app),
io = socketIo.listen(server);
var graph = {nodes : [], links : []}
server.listen(8080, function(){
console.log('server is listening on localhost:8080');
});
app.use(express.static(__dirname + '/'));
io.on('connect', function(socket){
// dump some test data
socket.on('test', function(){
// this just creates a few nodes in an array
var data = { ... }
graph = data;
io.emit('test', graph);
});
socket.on('eventNodeDragStart', function(index){
console.log('event node drag start: ' + index);
// undefiend, the graph.nodes is empty here
console.log(graph.nodes[index] + "\n\n");
// cannot read property of undefined
// also missing error handler on 'socket'
if(graph.nodes[index].locked) return;
graph.nodes[index].locked = true;
io.emit('eventNodeDragStart', index);
});
});
Solved the problem by replacing this line:
io.on('connect', function(socket){
with this:
io.sockets.on('connect', function(socket){
Not sure why it works, but it does.

Node.js- Make array in app.js available in a module

In my Node app.js, I don't necessary need to have my array openConnections global...but I want it in app.js and accessible by module sse_server.js for the sseStart function. How can I do this?
app.js:
var express = require('express');
var morgan = require('morgan');
var fs = require("fs");
var createDomain = require("domain").create;
var app = express();
app.use(express.static(__dirname + '/app/static/views'));
app.use(express.static(__dirname + '/app/static'));
app.use(express.static(__dirname + '/app/images'));
app.use(express.static(__dirname + '/app'));
var openConnections = [];
var sseStart = require(__dirname + '/app/scripts/sse_server.js');
app.get('/subscribe', sseStart);
var callAllApiAndSave = require('./app/scripts/api_scripts/call_all_api.js');
var db = require(__dirname + '/app/data/db.js');
var mainDomain = new createDomain();
mainDomain.run(function () {
mainDomain.on('error', function() {
console.log('yoyoyoyoyoyoyoyoyoyoyoyoyoyoyo');
});
mainDomain.on('error', function(er) {
console.log('error, but oh well', er.message);
});
db.connectDatabase();
setInterval(callAllApiAndSave, 120000);
var server = app.listen(9000, function() {
console.log('Listening on port %d', server.address().port);
});
});
sse_start.js:
function sseStart(req, res) {
console.log(req);
// set timeout as high as possible
req.socket.setTimeout(Infinity);
// send headers for event-stream connection
// see spec for more information
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
res.write('\n');
// push this res object to our global variable
console.log("Creating SSE connection for " + req.connection.remoteAddress);
openConnections.push(res);
console.log("Total current live connections: " +
openConnections.length);
// When the request is closed, e.g. the browser window
// is closed. We search through the open connections
// array and remove this connection.
req.on("close", function() {
console.log("Closing SSE connection for "
+ req.connection.remoteAddress);
openConnections = openConnections.filter(function(storedRes) {
if (storedRes !== res) {
return storedRes;
}
});
if (!openConnections) openConnections = [];
console.log("Total current live connections: " +
openConnections.length);
});
}
module.exports = sseStart;
Looking at the code you posted openConnections is only used in sse_start.js so why not put it there?
If you really want to share that array between those two files you can just put it in a separate module and require it in app.js and sse_start.js.

Node.JS run Sandbox in REST service

I am using Node Restify Module to create a REST service that accepts POST. Within the service I am trying to create a Sandboxed process using Node Sandbox module because we will be running dynamically inserted Javascript and if something goes wrong, I dont want it to affect the main Node instance.
When I try to create the Sandbox, something goes wrong and causes the REST service to come back empty.
Here is my code
var restify = require('restify');
var Sandbox = require("sandbox");
var logic;
function createSandbox(body) {
var s = new Sandbox();
s.run("1 + 1", function(output) {
logic = body.names + " has " + output.result;
});
}
function respond(req, res, next) {
createSandbox(req.body);
res.send(logic);
}
var server = restify.createServer();
server.use(restify.bodyParser({
mapParams: false
}));
server.post('/hello/:name', respond);
server.head('/hello/:name', respond);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
In my http request I have {"names":"rob"} in the body
I am expecting the following response
rob has 2
------------UPDATE-------------------
This works
var restify = require('restify');
var Sandbox = require("sandbox");
var logic;
function respond(req, res, next) {
var s = new Sandbox();
s.run("1 + 1", function(output) {
logic = req.body.names + " has " + output.result;
res.send(logic);
});
}
var server = restify.createServer();
server.use(restify.bodyParser({
mapParams: false
}));
server.post('/run/:id', respond);
server.head('/run/:id', respond);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
Sandbox.run() is asyncronous. It just sets the sandbox up to run at a later time and returns immediately before the code it sandboxes is actually run, so you're reading logic before it's set.
A quick demo;
var Sandbox = require("sandbox");
function createSandbox() {
var s = new Sandbox();
s.run("1 + 1", function(output) {
console.log("inside");
});
}
createSandbox();
console.log("outside");
> outside
> inside

Categories