L'exécution d'un node.js script toutes les 10 secondes
J'ai juste commencé à l'aide de Node.js et je vais maintenant essayer de faire de mon script de s'exécuter en arrière-plan toutes les 10 secondes comme un démon en attente de quelque chose à faire, quand il y a quelque chose à courir à partir de la base de données qu'Il lit la sortie du programme et certaines tâches, en fonction de la sortie.
C'est ce que j'ai pu faire jusqu'à présent, Il fonctionne exactement comme je l'ai prévu, mais ne peut exécuter qu'une seule 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
Pas sûr que vous soins - mais votre IP regex n'est pas très précis - il acceptons
Si vous souhaitez exécuter la
Merci pour l'astuce Benjamin!
999.999.999.999
par exemple.Si vous souhaitez exécuter la
db.query("SELECT * FROM queue ...
avec succès de rappel tous les 10 sec?Merci pour l'astuce Benjamin!
OriginalL'auteur user3246446 | 2014-01-30
Vous devez vous connecter pour publier un commentaire.
Mettre votre base de données d'une requête dans une fonction de rappel, et de faire le rappel du feu à nouveau la fonction 10sec plus tard:
Donc il va faire de votre requête, puis attendre 10sec avant de tirer une autre.
OriginalL'auteur DrakaSAN
Juste avoir votre programme à exécuter en continu et l'utilisation
setTimeout
pour ré-exécuter la logique principale sur une minuterie. Il est égalementsetInterval
qui est tentant, mais tu risques de départ d'une course avant la avant l'exécution complète. Voici le modèle de base.Pas exactement clair ce que vous demandez, mais oui.
Je ne suis pas entièrement sûr de ce que tu veux dire avec lastAsyncThing, depuis la fin du script dans des endroits différents selon si le programme réussit ou pas. Où exactement j'ai mis le délai d'attente?
OriginalL'auteur Peter Lyons
l'exécution de ce script par forever paquet - https://npmjs.org/package/forever
De remplir exécuter ce script en tâche de fond, détachés de la console.
Pendant 10 secondes timeuout vous pouvez utiliser
Plus d'infos là - http://www.w3schools.com/jsref/met_win_setinterval.asp
setInterval
est une mauvaise idée, tant que la tâche en cours pourrait encore être en cours d'exécution pour une raison quelconque, puis vous pourrait déclencher un autre temps. Il est préférable de se flétrir définir un délai d'attente de 10 secondes dans le succès (qui en effet n'aboutirait pas à une exécution de toutes les 10sec mais 10sec + temps écoulé) ou de mesurer le temps écoulé, le début de la tâche complète de la tâche et utiliser la différence pour le délai d'attente.probablement nous avons besoin d'une variable à la serrure pour éliminer les conditions de course?
OriginalL'auteur vodolaz095