每10秒运行一次node.js脚本 [英] Running a node.js script every 10 seconds

查看:136
本文介绍了每10秒运行一次node.js脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用Node.js,现在我想让我的脚本每10秒在后台运行一次,就像守护程序在等待某些事情要做,当数据库中有某些事情要运行时,它会读取该程序并根据输出执行某些任务.

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.

到目前为止,这是我能够做到的,它可以按我的预期工作,但即使在后台也只能运行一次.如何使它每10秒像守护程序一样运行一次?

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?

代码:

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

推荐答案

将您的数据库查询放入具有回调的函数中,并使回调在10秒后再次触发该函数:

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

因此它将执行您的查询,然后等待10秒再触发另一个.

So it will do your query, then wait 10sec before firing another.

这篇关于每10秒运行一次node.js脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆