Exécution d’un script node.js toutes les 10 secondes

Je viens juste de commencer à utiliser Node.js et j’essaie maintenant de faire exécuter mon script en arrière-plan toutes les 10 secondes, comme un démon qui attend quelque chose à faire, lorsqu’il y a quelque chose à exécuter depuis la firebase database effectue certaines tâches en fonction de la sortie.

C’est ce que j’ai pu faire jusqu’à présent. Cela fonctionne exactement comme je le voulais mais ne peut être exécuté qu’une fois, même en arrière-plan. Comment puis-je le faire fonctionner comme un démon toutes les 10 secondes?

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 

Mettez votre requête de firebase database dans une fonction avec callback, et activez le rappel après 10 secondes plus tard:

 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 

Donc, il va faire votre requête, puis attendez 10 secondes avant de tirer une autre.

Laissez simplement votre programme fonctionner en continu et utilisez setTimeout pour réexécuter la logique principale sur un minuteur. Il y a aussi setInterval qui est tentant, mais vous risquez de démarrer une setInterval avant la fin de l’exécution précédente. Voici le modèle de base.

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

lancez ce script pour toujours – https://npmjs.org/package/forever

 $ forever script.js 

Ce remplissage exécute ce script en arrière-plan, détaché de la console.

Pendant 10 secondes, vous pouvez utiliser

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

Plus d’informations à ce sujet – http://www.w3schools.com/jsref/met_win_setinterval.asp