如何处理运行时间超过cron间隔的pm2 cron作业?

时间:2018-08-02 16:08:17

标签: node.js express pm2

我在pm2上运行了一个cron作业,它每隔5秒发送一次通知。尽管永远不会发生,但我担心该脚本将花费5秒钟以上的时间来运行。基本上,如果上一次运行需要6秒钟,那么我不想在下一次运行之前开始下一次运行。有没有办法仅在pm2中处理此问题?我发现的所有内容都说要使用Shell脚本来处理它,但是复制并在需要时转移到新服务器并不那么容易。

截至目前,我的cron作业仅在永无休止的while循环中运行(除非有错误),该循环最终要等待5秒钟。如果错误,它将退出并报告错误,然后重新启动,因为它是通过pm2运行的。不过,我对此实现并不感到兴奋。还有其他选择吗?

编辑以阐明我当前的逻辑-

pip 18.0 from /usr/local/lib/python2.7/dist-packages/pip (python 2.7)

这感觉像是一种绕过pm2的cron限制的简单方法。可能我只是偏执...我只是想确保我没有使用反模式。

2 个答案:

答案 0 :(得分:1)

您的意思是说您的cron作业在while循环中运行? PM2正在启动一个节点进程,其中包含一个等待5秒的永无休止的while循环?在我看来,您对cron的实现似乎不可行,也许您可​​以提供更多详细信息。

我会使用类似setTimeout的方法来代替cron。使用PM2运行脚本,脚本中的方法如下:

function sendMsg() {
  // do the work

  setTimeout(sendMsg, 5000); // call sendMsg after waiting 5 seconds
}

sendMsg();

通过这种方式,您的sendMsg函数可以花费所有需要的时间,并且下一次调用将在此后5秒钟开始。如果PM2崩溃,它将重新启动您的应用程序。

如果您希望每隔5秒钟执行一次,但仅当该方法未运行时,只需在方程式中添加一个跟踪变量,例如:

let doingWork = false;

function sendMsg() {
  if (!doingWork) {
    doingWork = true;
    // do the work
    doingWork = false;
  }
}

setInterval(sendMsg, 5000); // call sendMsg every 5 seconds

您可以将setInterval替换为脚本上的PM2 cron调用,但变量思路保持不变。

答案 1 :(得分:0)

要在结束之间准确地保持5000毫秒的时间:

var myAsyncLongAction = function(cb){
 // your long action here
 return cb();

 };

var fn = function(){
  setTimeout(function(){

      // your long action here
      myAsyncLongAction(function(){
          console.log(new Date().getTime());
          setImmediate(fn);
      });

  }, 5000)
};

fn();

要在开始操作之间准确地保持5000毫秒:

var myAsyncLongAction = function(cb){
   // your long action here

   setTimeout(function(){
    return cb();
  }, 1000);

};

  var fn = function(basedelay, delay){

    if(delay === undefined)
      delay = basedelay;

    setTimeout(function(){
            // your long action here
        var start = new Date().getTime();

        myAsyncLongAction(function(){

            var end = new Date().getTime();
            var gap = end - start;

            console.log("Action took "+(gap)+" ms, send next action in : "+(basedelay - gap)+" ms");
            setImmediate(fn, basedelay, (gap < basedelay ? 1 : basedelay - gap));
        });

    }, delay);
  };

  fn(5000);