Can't send fetched data to my socket.io stream? - javascript

I'm trying to switch from single mysql-queries to mysql-pool connection, so users can share one mysql-connection, but I'm not familiar with this at all (also new to nodejs/socket.io).
The following code is what I've done so far to send data every second to the socket in an array:
var
port = process.env.OPENSHIFT_NODEJS_PORT || 8000,
ip = process.env.OPENSHIFT_NODEJS_IP || '127.0.0.1',
app = require('http').createServer(handler),
fs = require('fs'),
request = require('request'),
mysql = require('mysql'),
moment = require('moment'),
tz = require('moment-timezone'),
pool = mysql.createPool({
connectionLimit: 100,
host: 'xxx',
user: 'xxx',
password: 'xxx',
database: 'xxx',
debug: false,
port: 3306}),
socketArray = [],
POLLING_INTERVAL = 1000,
pollingTimer;
moment.tz.setDefault("Europe/Berlin");
var io = require('socket.io').listen(app);
io.set('origins', '*:*');
function time()
{
output = new Date();
output = moment().format('(H:mm:ss.SS) ');
return output;
}
function handler(req,res)
{
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.statusCode = 200;
res.connection.setTimeout(0);
res.end();
}
app.listen(port,ip);
function pollingLoop () {
if (socketArray.length === 0) {
// no connections, wait and try again
setTimeout(pollingLoop, POLLING_INTERVAL);
return; // continue without sending mysql query
}
pool.getConnection(function(err,connection){
if (err) { console.log({"code" : 100, "status" : "connection-db error"}); return; }
console.log('connected as id ' + connection.threadId);
console.log('socketArray length: ' + socketArray.length);
var selection =
"SELECT\
a.`id`,a.`product_id` AS pid,a.`random` AS nr,a.`price`,a.`price_end` AS pe,\
TIMESTAMPDIFF(SECOND,NOW(),a.`datetime`) AS duration,\
ABS(TIMESTAMPDIFF(SECOND,NOW(),b.`date`)) AS hb\
FROM `auctions` AS a\
LEFT JOIN `auctions_bids` AS b ON b.`auction_id` = a.`id`\
WHERE TIMESTAMPDIFF(SECOND,NOW(),a.`datetime`) > '-1'\
GROUP BY a.`id`\
ORDER BY `duration` DESC,`id` DESC LIMIT 15";
var streamArray = [], lg = '';
var query = connection.query(selection, function(err, results, rows){
lg += ('id: '+results[0].id+' ('+results[0].duration+') ');
if
(
((results[0].duration < 2 || results[0].duration <= results[0].nr) && (results[0].price <= results[0].pe))
||
((results[0].duration < 2 || results[0].duration <= results[0].nr) && (results[0].hb > 0 && results[0].hb < 30))
)
{
min = 3;
max = 5;
rand = Math.floor(Math.random()*(max-min+1)+min);
price = results[0].price+0.01;
price = price.toFixed(2);
pool.query('UPDATE `auctions` SET `random` = ?,`price` = ?, `datetime` = DATE_ADD(`datetime`,INTERVAL(17-TIMESTAMPDIFF(SECOND,NOW(),`datetime`))SECOND) WHERE `id` = ?',[rand, price, results[0].id]);
console.log(time()+'UPDATED id '+results[0].id+': random ('+rand+') price ('+price+'€)');
}
streamArray.push(results[0]);
updateSockets({ streamArray: streamArray });
console.log("auctions pushed: " + streamArray);
connection.release();
setTimeout(pollingLoop, POLLING_INTERVAL);
});
console.log(time()+lg+' C: '+socketArray.length);
});
}
pollingLoop();
io.sockets.on('connection', function(socket) {
socket.on('disconnect', function() {
clearTimeout(pollingTimer);
var socketIndex = socketArray.indexOf(socket);
console.log(time()+'SOCKET-ID = %s DISCONNECTED', socketIndex);
if (~socketIndex) { socketArray.splice(socketIndex, 1); }
});
console.log(time()+'NEW SOCKET CONNECTED!');
socketArray.push(socket);
});
var updateSockets = function(data) {
socketArray.forEach(function(tmpSocket) { tmpSocket.volatile.emit('stream', data); });
};
console.log(time()+'server.js executed\n');
But this doesn't send me any data to the WebSocket. Is this approach (code-structure) even correct? Previously I used query.on('results') to get data like this:
var selection = "SELECT * FROM auctions";
var query = mysql.query(selection), auctions = [];
query.on('result', function(auction) {
console.log('id: '+auction.id+' ('+auction.duration+') ');
});
This worked fine showing data with auction.row but how to do this in my mysql pool connection?
Also after some seconds I'm getting an error that release() isn't even defined, but it's listed in the mysql-module documentation... so I think my whole logical process is somehow incorrect.
Should I use connection.end() and .release() at all? Because the
connection should never end.
Should I still use setInterval(function () { mysql.query('SELECT
1'); }, 5000); as answered in another StackOverflow question to keep
the connection alive here? (nodejs mysql Error: Connection lost The server closed the connection)
(Appreciate any tips or answers to even some of my questions! Better some answers than none, because I experienced that this topic isn't answered much at all.)
EDIT:
Updated my whole code (see above). Output looks like this now: http://s21.postimg.org/avsxa87rb/output.jpg
So the stream gets the data, but in the console.log is nothing and there's this javascript error?

You should be creating a pool, and using getConnection on that pool. Then, when you're done with the connection, release it. Additionally, you do not need to stop the pollingLoop or start it for each connection, one loop is enough.
I didn't understand the if statement with conditions, so i omitted it. It likely needs to go somewhere else.
var socketArr = [];
function handler(req, res) {
res.statusCode = 200;
res.connection.setTimeout(0);
res.end();
}
app.listen(port, ip);
var pool = mysql.createPool({
host : 'example.org',
user : 'bob',
password : 'secret'
});
function pollingLoop () {
if (socketArr.length === 0) {
// no connections, wait and try again
setTimeout(pollingLoop, 1000);
return; // continue without sending mysql query
}
pool.getConnection(function (err, connection) {
if (err) {
console.log({
"code": 100,
"status": "Error in connection database"
});
return;
}
console.log('connected as id ' + connection.threadId);
var selection = "SELECT * FROM auctions";
var streamArray = [],
lg = '';
var query = connection.query(selection, function (err, results, fields, rows) {
lg += ('id: ' + results[0].id + ' (' + results[0].duration + ') ');
/*if (conditions) {
var query_update = connection.query('UPDATE `auctions` SET `price` = ? WHERE `id` = ?', [price, auction.id]);
console.log(time() + 'UPDATED id ' + auction.id + ': price (' + price + '€)');
}*/
streamArray.push(results);
updateSockets({
streamArray: streamArray
});
console.log("auctions pushed: " + streamArray);
connection.release();
setTimeout(pollingLoop, 1000);
});
console.log(time() + lg + ' C: ' + socketArr.length);
});
}
// start loop
pollingLoop();
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
var socketIndex = socketArr.indexOf(socket);
console.log(time() + 'SOCKET-ID = %s DISCONNECTED', socketIndex);
if (~socketIndex) {
socketArr.splice(socketIndex, 1);
}
});
console.log(time() + 'NEW SOCKET CONNECTED!');
socketArr.push(socket);
});
var updateSockets = function (data) {
socketArr.forEach(function (tmpSocket) {
tmpSocket.volatile.emit('stream', data);
});
};

Related

Render my ejs file after my query finishes

I want to make sure that my application will only call res.render('pages/students' ...) after all my queries finishes and I get all the necessary data. However, I completely have no clue how to do this at all and I am having trouble applying all the examples I see online onto my code. Can someone give me a hand? (There are two con.query(...) in my route. I want to only render('pages/students'...) after both of these con.query completely finishes. Therefore, I am using async to run all my queries to completion. However now for some reason my page wont event load.
app.get('/admin', function(req, res) {
var sql =
'SELECT events.id, name, description, MONTHNAME(start_time) AS month, DAY(start_time) AS day, ' +
"YEAR(start_time) AS year, DATE_FORMAT(start_time, '%h:%i%p') AS start_time, HOUR(start_time) AS start_hour, MINUTE(start_time) AS start_minute, " +
"DATE_FORMAT(end_time, '%h:%i%p') AS end_time, HOUR(end_time) AS end_hour, MINUTE(end_time) AS end_minute, location, max_capacity, hidden_sign_up, " +
'eventleaders.first_name AS eventLeader FROM events LEFT JOIN eventleaders_has_events ON events.id = eventleaders_has_events.events_id ' +
'LEFT JOIN eventleaders ON eventleaders_has_events.eventleaders_id = eventleaders.id;';
var events = {};
con.query(sql, function(err, results) {
if (err) throw err;
async.forEachOf(results, function(result, key, callback) {
var date = result.month + ' ' + result.day + ', ' + result.year;
var other = 'N/A';
if (result.other !== null) {
other = result.other;
}
if (typeof events[date] === 'undefined') {
events[date] = {};
}
var studentAttendees = {};
var sql =
'SELECT * FROM students INNER JOIN students_has_events ON students.id = students_has_events.Students_id ' +
'WHERE students_has_events.Events_id = ?';
var values = [result.id];
con.query(sql, values, function(err, results1) {
if (err) throw err;
async.forEachOf(results1, function(result1, key, callback) {
studentAttendees[result1.first_name + ' ' + result1.last_name] = {
netID: result1.netID,
phoneNumber: result1.phone,
email: result1.email
};
});
//still need to get the event leader attendees
events[date][result.name] = {
startTime: result.start_time,
location: result.location,
endTime: result.end_time,
description: result.description,
eventLeader: result.eventLeader,
numberRegistered: result.hidden_sign_up,
maxCapacity: result.max_capacity,
poster: '/images/sample.jpg',
other: other,
attendees: studentAttendees
};
});
});
});
});
Two options:
app.get('/admin', function(req, res) {
...
con.query(sql, function(err, result) {
...
con.query(sql, values, function(err, result) {
events[date][currRecord.name] = {
...
};
// put it here
console.log(events);
res.render('pages/admin', {
events: events
});
});
}
});
});
Or use the Promise version of mysql
const mysql = require('mysql2/promise');
// make this async
app.get('/admin', async function(req, res) {
try {
...
// might want to move this elsewhere inside async function
const con = await mysql.createConnection({host:'localhost', user: 'root', database: 'test'});
const result1 = await con.query(sql);
// run your logic preferably inside map
// result2 is an array of Promises
const result2 = result1.map((result, index) => {
var currRecord = result[index];
var date =
currRecord.month + ' ' + currRecord.day + ', ' + currRecord.year;
var other = 'N/A';
if (currRecord.other !== null) {
console.log('here');
other = currRecord.other;
}
if (typeof events[date] === 'undefined') {
events[date] = {};
}
//get all the student attendees of this event
var studentAttendees = {};
var sql =
'SELECT * FROM students INNER JOIN students_has_events ON students.id = students_has_events.Students_id ' +
'WHERE students_has_events.Events_id = ?';
var values = [currRecord.id];
return con.query(sql)
})
// result3 is an array of results. If your results is also an array, the structure might look lik [[student], [student]] etc.
const result3 = await Promise.all(result2);
// run your logic to get events
console.log(events);
res.render('pages/admin', {
events: events
});
} catch (e) {
// handle error
console.error(e)
}
});

Syntax Error when using multiple parameter substitutions in a MYSQL Query

I need to Update MYSQL data using JS after I receive an AJAX Post request
I made a variable for the MYSQL Update Query and I'm passing in the field to be updated, new value, row to be updated as an array. But for some reason those variables are read with single quotes(') which, I believe, is causing me a syntax error.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var MYSQL = require('mysql');
var server = require('http').createServer(app);
//declaring var 'conn' for MYSQL.createPool
let columns = new Array();
// Piece of code Starting the Server
// Routing
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(express.static(path.join(__dirname, 'public')));
app.post('/', function (req, res) {
updateWorkbook(req.body);
res.send('Thanks for the data.');
});
//This is the function extracts the row, field value that need to be updated from the AJAX request
function updateWorkbook( data ){
getcolumns().then( function (columns) {
console.log("Columns got returned to Updateworkbook function")
for (let d = 0; d < data.length; d++) {
let rowToUpdate = data[d].id.replace('row_', '').split('_')[0];
let fieldToUpdate = data[d].id.replace('row_', '').split('_')[1];
let newValue = data[d].value;
console.log('row,field,value: ' + rowToUpdate + '|' + fieldToUpdate + '|' + newValue);
let key_to_replace;
for(let i = 0; i < columns.length; i++) {
let looper = columns[i].toLowerCase()
if (looper === fieldToUpdate) {
key_to_replace = columns[i]
}
}
let field_to_replace = key_to_replace.toString();
console.log(field_to_replace) //It prints out a normal string value here
updatemysql(field_to_replace, newValue, rowToUpdate);
}
});
};
//This is the function which updates MYSQL data
function updatemysql(field, newval, row) {
var sql = "UPDATE mydb.mytable SET ? = ? WHERE ROW_ID = ?;";
conn.getConnection( function (err, connection) {
if (err){
return cb(err);
connection.release();
}
console.log("Connection got established")
conn.query(sql, [field, newval, row], function (error, results){
if (error){
throw error;
connection.release();
}
console.log('Data Updated');
connection.release();
});
});
}
//Function to extract all columns from MYSQL and stores them in an array
function getcolumns() {
return new Promise(function(resolve, reject) {
console.log("getcolumns got initiated")
conn.getConnection( function (err, connection) {
if (err){
return cb(err);
connection.release();
return reject(err);
}
else {
var sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'mytable';"
conn.query(sql, function (error, results){
for (let i = 0; i < results.length; i++) {
columns.push(results[i]['COLUMN_NAME'])
}
resolve(columns);
console.log("Extracted columns")
connection.release();
});
}
});
});
};
Here's the error I receive:
Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Source_of_Phone_Number_' = 'Test' WHERE ROW_ID = '1'' at line 1`
Source_of_Phone_Number_ is the key_to_replace.
Test is the newValue.
1 is the Row_ID.
There is a problem in function updatemysql(), which uses the following SQL :
var sql = "UPDATE mydb.mytable SET ? = ? WHERE ROW_ID = ?;";
You cannot pass a column name as a parameter.
You would need to change this to :
var sql = "UPDATE mydb.mytable SET " + field + " = ? WHERE ROW_ID = ?;";
Accordingly, only two parameters should be passed to the query :
conn.query(sql, [newval, row], function (error, results){ ... });

Server crash, sending message at restart (Node.js / Socket.io)

Hey guys i am doing a message system all is working fine but now i want to add the thing that if the server crash and restart the message that have been send during this time will be send at the restart of the server. I am trying to save the information of the message in the client side and make a "waiting" system that will wait to a server response. So i wanted to know how can i do that "waiting" system because now i am doing like that :
while (socket.connected === false) {
}
But that make bug the client because the infinit loop is way too fast ... so is that possible to set a timer ? (i have already tried but i dind't find how to make a good timer in a loop).
Or maybe i am totaly wrong and i haven't to do a waiting system but an other thing so tell me if my technic will not work or if there is one better :)
So here is my code :
Client.js (startTchat is called when someone is connected)
(function($){
var socket = io.connect('http://localhost:1337');
var lastmsg = [];
var me_id = [];
var friend_ = [];
var conv_ = [];
var isPlace_ = [];
var isLocation_ = [];
var me_ = [];
var my_id;
startTchat = function(user_id, username, friend_id, conv_id, isPlace, isLocalisation) {
my_id = user_id;
socket.emit('login_chat', {
id : user_id,
username : username,
friend : friend_id,
conv : conv_id,
isPlace : isPlace,
isLocalisation : isLocalisation,
})
};
/**
* Error
*/
socket.on('error', function(err){
alert(err);
});
/**
* Messages
*/
$('#chat_form').submit(function(event){
var a = 0;
while (socket.connected === false) {
}
event.preventDefault();
console.log('ME', my_id, 'TAB', me_id);
socket.emit('new_msg', {message: $('#message').val() }, me_id[my_id], friend_[my_id], conv_[my_id], isPlace_[my_id], isLocation_[my_id], me_[my_id]);
if (a === 1) {
console.log('HEYYYYYYYYYY', my_id);
}
$('#message').val('');
$('#message').focus();
});
socket.on('new_msg', function(message, me, id_receiver, id_transmiter){
if (me.id === id_receiver || me.id === id_transmiter) {
if (lastmsg != message.user.id) {
$('#new_message').append('<span class="time_date"> ' + message.h + ' : ' + message.m + ' | ' + message.y + '-' + message.m + '-' + message.d + ' | ' + message.user.username + '</span>'
+ '<p>' + message.message + '</p>\n'
);
lastmsg = message.user.id;
} else {
$('#new_message').append('<p>' + message.message + '</p>'
);
}
}
});
/**
* Login
*/
socket.on('new_user', function(user, friend, conv, isPlace, isLocation){
me_id[user.id] = user.id;
friend_[user.id] = friend;
conv_[user.id] = conv;
isPlace_[user.id] = isPlace;
me_[user.id] = user;
isLocation_[user.id] = isLocation;
$('#new_user').append('<div class="chat_list active_chat" id="' + user.id + '">\n' +
' <div class="chat_people">\n' +
' <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>\n' +
' <div class="chat_ib">\n' +
' <h5>' + user.username + ' <span class="chat_date">Id : ' + user.id + '</span></h5>\n' +
' </div>\n' +
' </div>\n' +
' </div>');
});
/**
* Disconnect
*/
socket.on('disc_user', function(user){
$('#' + user.id).remove();
})
})(jQuery);
And server.js :
var http = require('http');
var MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'msg';
MongoClient.connect(url, function(err, client) {
if (err)
throw err;
console.log('MongoDB connected ...');
httpServer = http.createServer(function(req, res) {
console.log('This is a test');
res.end('Hello World');
});
httpServer.listen(1337);
var io = require('socket.io').listen(httpServer);
var users = {};
var messages = [];
io.sockets.on('connection', function (socket) {
const collection = client.db(dbName).collection('MessageUser');
var me = false;
var friend = false;
var conv = false;
var isPlace = false;
var room = false;
var isLocalisation = false;
for(var k in users) {
socket.emit('new_user', users[k]);
}
/**
* Login
*/
socket.on('login_chat', function (user) {
me = user;
friend = user.friend;
isPlace = user.isPlace;
conv = user.conv;
isLocalisation = user.isLocalisation;
if (isPlace === 0) {
room = user.conv;
} else {
room = user.conv + '-Place';
}
socket.join(room);
//console.log('New user : ', me.username, ' - id : ', me.id);
users[me.id] = me;
io.sockets.emit('new_user', me, friend, conv, isPlace, isLocalisation);
});
/**
* Disconnect
*/
socket.on('disconnect', function() {
if (!me) {
return false;
}
delete users[me.id];
io.sockets.emit('disc_user', me);
});
/**
* Message receive
*/
socket.on('new_msg', function(message, me_id, friend_, conv_, isPlace_, isLocalisation_, me_){
if (message.message !== '') {
message.user = me;
date = new Date();
message.h = date.getHours();
message.m = date.getMinutes();
message.y = date.getFullYear();
message.m = date.getMonth();
message.d = date.getDate();
console.log(message);
messages.push(message);
msg = {};
msg.content = message.message;
msg.sendAt = new Date();
msg.idTransmitter = me.id;
if (isPlace === 0) {
msg.idReceiver = friend;
} else {
msg.idReceiver = conv;
}
msg.idConversation = conv;
msg.isPlace = isPlace;
msg.isLocalisation = isLocalisation;
collection.insertOne(msg);
console.log('---1---', msg.idReceiver, '---2---', msg.idTransmitter, '---3---', me);
io.to(room).emit('new_msg', message, me, msg.idReceiver, msg.idTransmitter);
}
});
});
});
ps : Tell me if you need more info, sorry if i forget something that my first time using js, node and socket.io :)
while (socket.connected === false) {
}
Don't do that, it will block your page and hold your processor to 100%.
Instead, use setTimeout. It's the equivalent of sleep in javascript. You need to refactor your code to call setTimeout in a recursive fashion, and count the number of "retries" (if you want to stop at some point).
Code:
$('#chat_form').submit(function(event){
var retries = 0, max_retries = 10;
function tryNewMessage() {
if (socket.connected === false) {
if (retries >= max_retries) return; //handle max_retries properly in your code
//this is where you sleep for 1 second, waiting for the server to come online
setTimeout(tryNewMessage, 1000);
retries++;
}
else {
var a = 0;
event.preventDefault();
console.log('ME', my_id, 'TAB', me_id);
socket.emit('new_msg', {message: $('#message').val() }, me_id[my_id], friend_[my_id], conv_[my_id], isPlace_[my_id], isLocation_[my_id], me_[my_id]);
if (a === 1) {
console.log('HEYYYYYYYYYY', my_id);
}
$('#message').val('');
$('#message').focus();
}
}
tryNewMessage();
});

When using the expressjs in Nodejs, the server keeps close_wait status after a few thousands of requests

I put the code below onto my server:
var express = require('express');
var app = express();
var mysql = require('mysql');
var db = mysql.createPool({host:'192.168.1.234', user:'root', password:'123456', database:'db_xuyou_test', port:3306});
app.post('/query', function (req, res){
s = {};
platform = Number(req.query['platform']) * 100000000;
platform_upper = platform + 99999999;
appv = Number(req.query['appv']) * 10000;
resource = Number(req.query['res']) * 1;
id = platform + appv + resource;
resource_upper = platform + appv + 9999;
sql = 'select appv from (select min(id) as min_id from download where id >= ? and id <= ?) as a inner join download on a.min_id = download.id';
db.query(sql, [platform, platform_upper], function(err, row) {
if (err) {
console.error(err);
res.end();
return;
}
if (row.length <= 0) {
s['code'] = 2;
s['message'] = 'update!';
res.send(s);
console.log(s);
return;
}
if (Number(row[0]['appv']) > appv) {
s['code'] = 2;
s['message'] = 'update!';
res.send(s);
console.log(s);
return;
}
sql = 'select res as version, versionName, ip, port, filename from download where id > ? and id <= ? order by id';
db.query(sql, [id, resource_upper], function(err2, resRow) {
if (err2) {
console.error(err2);
res.end();
return;
}
if (resRow.length <= 0) {
s['code'] = 0;
s['message'] = '';
res.send(s);
console.log(s);
return;
}
s['code'] = 1;
s['message'] = '';
s['versionData'] = resRow;
console.log(s);
res.send(s);
});
});
});
app.listen(3000, '0.0.0.0');
And I wrote a test which sends thousands of requests to the server. But very weirdly, the the server suddenly ran into close_wait status after processing a few thousands of requests.
As the code describes, it processes the request by selecting the data from the database and send the result back to the clients and the procedure will end.
Why it turns out to be close_wait?? How to solve it?
Thanks in advance.

Running a node.js script every 10 seconds

I just started using Node.js and I'm now trying to make my script run in the background every 10 seconds like a daemon waiting for something to do, when there is something to run from the database It reads the output from the program and does certain tasks depending on the output.
This is what I've been able to do so far, It works just as I intended but can only run once even in the background. How can I make it run like a daemon every 10 seconds?
Code:
var spawn = require('child_process').spawn;
var mysql = require('mysql');
var JSFtp = require('jsftp');
var check = require('node-validator').check;
var sanitize = require('node-validator').sanitize;
//Setup the db connection
var db = mysql.createConnection({
host : 'db',
port : 3306,
database: 'db',
user : 'db',
password : 'db'
});
//Make the connection
db.connect(function(err){
if(err != null) {
res.end('Error connecting to mysql:' + err+'\n');
}
});
var die = function(msg){
console.error(msg);
process.exit(1);
}
function ip2long ( ip_address ) {
var output = false;
var parts = [];
if (ip_address.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) {
parts = ip_address.split('.');
output = ( parts[0] * 16777216 +
( parts[1] * 65536 ) +
( parts[2] * 256 ) +
( parts[3] * 1 ) );
}
return output;
}
db.query("SELECT * FROM queue WHERE cooldown > UNIX_TIMESTAMP(NOW()) AND simulated=0 ORDER BY cooldown DESC LIMIT 1", function(err, rows){
if(err != null){
die("Query error: " + err);
}
if(rows < 1){
die("No rows");
}
//Set the vars from the query
var name = rows[0]['name'];
var ip = rows[0]['ip'];
var iterations = rows[0]['runs'];
var bin = "/home/hoar/sum/run"
var args = ['arg='+name, 'arg2='+iterations, 'path=/var/www/upload/'+name+'.html', 'output=log.log'];
var proc = spawn(bin, args);
var time = "/.*/";
var pct = "/^\d/";
var name = rows[0]['name'];
var ip = rows[0]['ip'];
var iterations = rows[0]['runs'];
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function(data) {
var str = data.toString();
var s = str.split("|");
var p = s[0].split("/");
var t = (s[1] == null) ? "" : s[1];
if(p != null && s[0] != "#"){ //Needed to check for # because the program prints this as first line, which is good then we can do the query further done only once.
//Check the return numbers from simc to see how many sims it has done
if(parseInt(p[0]) < parseInt(p[1])){
//Check if the 6th match is a number and the 7th only contains letters
if(t != null){
var time = t.replace(/(\r\n|\n|\r)/gm,""); //Remove any line disturbers for db
//Update the database with the amount of time left on the simulation
db.query("UPDATE `queue` SET `status`=" + db.escape(time) + " WHERE (`name`=" + name + ")");
//console.log(p[0]+"/"+p[1] + " - " + t + " left");
}
//console.log(p[0]+"/"+p[1] + " iterations done");
}
}else{
//If the stdout is null run this query since we don't want to run this more than once.
db.query("UPDATE `queue` SET `simulated`='2' WHERE (`name`=" + name + " AND simulated!='2')");
//console.log("Updated db to 2");
}
});
proc.stderr.on('data', function (data) {
var str = data.toString();
//If the program returns stderr we want to make sure it stops and we update the database to let the user know.
if(str.indexOf("ERROR! Setup failure...")){
//Update the database with the amount of time left on the simulation
db.query("UPDATE `queue` SET `simulated`='3' WHERE (`name`=" + name + ")");
//Kill the DB connection
db.destroy();
die("There was an error: " + data);
}
});
proc.on('exit', function (code) {
//Setup the ftp connection
var ftp = new JSFtp({
host: "ftp",
port: 21,
user: "ftp",
pass: "ftp"
});
//Simulation ended with success update the database and kill.
db.query("UPDATE `queue` SET `simulated`='1' WHERE (`name`=" + name + " AND simulated='2')");
ftp.put('/var/www/upload/'+rows[0]['name']+'.html', 'public_html/mysite/'+ip2long(rows[0]['ip'])+'/'+rows[0]['name']+'.html', function(hadError) {
if (!hadError)
console.log("FTP error");
ftp.raw.quit();
});
db.destroy();
//die("Simulation is done");
});
});//end sql
Put your db query in a function with callback, and make the callback fire the function again 10sec later:
function mydbquery(callback) {
db.query("SELECT * FROM queue WHERE cooldown > UNIX_TIMESTAMP(NOW()) AND simulated=0 ORDER BY cooldown DESC LIMIT 1", function(err, rows){
if(err != null){
die("Query error: " + err);
}
if(rows < 1){
die("No rows");
}
//Set the vars from the query
var name = rows[0]['name'];
var ip = rows[0]['ip'];
var iterations = rows[0]['runs'];
var bin = "/home/hoar/sum/run"
var args = ['arg='+name, 'arg2='+iterations, 'path=/var/www/upload/'+name+'.html', 'output=log.log'];
var proc = spawn(bin, args);
var time = "/.*/";
var pct = "/^\d/";
var name = rows[0]['name'];
var ip = rows[0]['ip'];
var iterations = rows[0]['runs'];
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function(data) {
var str = data.toString();
var s = str.split("|");
var p = s[0].split("/");
var t = (s[1] == null) ? "" : s[1];
if(p != null && s[0] != "#"){ //Needed to check for # because the program prints this as first line, which is good then we can do the query further done only once.
//Check the return numbers from simc to see how many sims it has done
if(parseInt(p[0]) < parseInt(p[1])){
//Check if the 6th match is a number and the 7th only contains letters
if(t != null){
var time = t.replace(/(\r\n|\n|\r)/gm,""); //Remove any line disturbers for db
//Update the database with the amount of time left on the simulation
db.query("UPDATE `queue` SET `status`=" + db.escape(time) + " WHERE (`name`=" + name + ")");
//console.log(p[0]+"/"+p[1] + " - " + t + " left");
}
//console.log(p[0]+"/"+p[1] + " iterations done");
}
}else{
//If the stdout is null run this query since we don't want to run this more than once.
db.query("UPDATE `queue` SET `simulated`='2' WHERE (`name`=" + name + " AND simulated!='2')");
//console.log("Updated db to 2");
}
});
proc.stderr.on('data', function (data) {
var str = data.toString();
//If the program returns stderr we want to make sure it stops and we update the database to let the user know.
if(str.indexOf("ERROR! Setup failure...")){
//Update the database with the amount of time left on the simulation
db.query("UPDATE `queue` SET `simulated`='3' WHERE (`name`=" + name + ")");
//Kill the DB connection
db.destroy();
die("There was an error: " + data);
}
});
proc.on('exit', function (code) {
//Setup the ftp connection
var ftp = new JSFtp({
host: "ftp",
port: 21,
user: "ftp",
pass: "ftp"
});
//Simulation ended with success update the database and kill.
db.query("UPDATE `queue` SET `simulated`='1' WHERE (`name`=" + name + " AND simulated='2')");
ftp.put('/var/www/upload/'+rows[0]['name']+'.html', 'public_html/mysite/'+ip2long(rows[0]['ip'])+'/'+rows[0]['name']+'.html', function(hadError) {
if (!hadError)
console.log("FTP error");
ftp.raw.quit();
});
db.destroy();
//die("Simulation is done");
//NEW CODE!!!
callback();
//END OF NEW CODE
});
});//end sql
}
//NEW CODE!!!
function wait10sec(){
setTimeout(function(){
mydbquery(wait10sec);
}, 10000);
}
mydbquery(wait10sec);
//END OF NEW CODE
So it will do your query, then wait 10sec before firing another.
Just have your program run continuously and use setTimeout to re-execute the main logic on a timer. There is also setInterval which is tempting but you risk starting a run before the prior run completes. Here's the basic pattern.
function doMainStuff() {
//do all your stuff
lastAsyncThing(function (error) {
//When your final async thing is done, start the timer
if (error) {
//log error. Maybe exit if it's irrecoverable.
}
setTimeout(doMainStuff, 10 * 1000);
});
}
//when your program starts, do stuff right away.
doMainStuff();
run this script by forever package - https://npmjs.org/package/forever
$ forever script.js
This fill run this script in background, detached from console.
For 10 seconds timeuout you can use
setInterval(function(){...}, 10*1000);
More info is there - http://www.w3schools.com/jsref/met_win_setinterval.asp

Categories

Resources