Запуск node.js script каждые 10 секунд

Я только начал использовать Node.js, и теперь я пытаюсь сделать мой script запустившимся в фоновом режиме каждые 10 секунд, как демон, ожидающий чего-то, когда есть что-то для запуска из базы данных. считывает выходные данные из программы и выполняет определенные задачи в зависимости от выхода.

Это то, что я смог сделать до сих пор. Он работает так, как я предполагал, но может работать только один раз даже в фоновом режиме. Как я могу заставить его работать как демон каждые 10 секунд?

код:

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
3 ответа

Положите ваш запрос в функцию с обратным вызовом и снова вызовите функцию обратного вызова через 10 секунд:

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

Таким образом, он выполнит ваш запрос, а затем дождитесь 10 секунд до запуска другого.


Просто выполняйте свою программу непрерывно и используйте setTimeout для повторного запуска основной логики таймера. Существует также setInterval, который заманчиво, но вы рискуете начать прогон до завершения предыдущего запуска. Здесь основной шаблон.

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 irrecoverable.
 }
 setTimeout(doMainStuff, 10 * 1000);
 });
}
//when your program starts, do stuff right away.
doMainStuff();


запустите этот script навсегда пакет - https://npmjs.org/package/forever

$ forever script.js

Эта заливка запускает этот script в фоновом режиме, отсоединенный от консоли.

В течение 10 секунд вы можете использовать

setInterval(function(){...}, 10*1000);

Дополнительная информация есть http://www.w3schools.com/jsref/met_win_setinterval.asp

licensed under cc by-sa 3.0 with attribution.