我如何处理 运行 长于 cron 间隔的 pm2 cron 作业?
How can I handle pm2 cron jobs that run longer than the cron interval?
我在 pm2 上有一个 cron 作业 运行ning,它以 5 秒的间隔发送通知。虽然它永远不会发生,但我担心脚本将花费超过 5 秒的时间才能 运行。基本上,如果前一个 运行 需要 6 秒,我不想在第一个完成之前开始下一个 运行。有没有办法只在 pm2 中处理这个问题?我发现的所有内容都说使用 shell 脚本来处理它,但在需要时复制和移动到新服务器并不那么容易。
截至目前,我的 cron 作业只是 运行 在一个永无止境的 while 循环(除非出现错误)中运行,最后最多等待 5 秒。如果出错,它会退出并报告错误,然后重新启动,因为它正在通过 pm2 运行ning。不过,我对这个实现并不太兴奋。还有其他选择吗?
编辑以澄清我当前的逻辑 -
function runScript() {
while (!err) {
// do stuff
wait(5 seconds - however long 'do stuff' took) // if it took 1 second to 'do stuff', then it waits 4 seconds
}
}
runScript()
这感觉像是一种绕过 pm2 的 cron 限制的 hacky 方法。有可能我只是偏执狂...我只是想确保我没有使用反模式。
您在 while 循环中执行 cron 作业 运行 是什么意思? 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 秒间隔执行此操作,但仅当方法不是 运行ning 时,只需在等式中添加一个跟踪变量,例如:
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 调用,但变量的想法保持不变。
要在您的操作结束之间正好有 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);
我在 pm2 上有一个 cron 作业 运行ning,它以 5 秒的间隔发送通知。虽然它永远不会发生,但我担心脚本将花费超过 5 秒的时间才能 运行。基本上,如果前一个 运行 需要 6 秒,我不想在第一个完成之前开始下一个 运行。有没有办法只在 pm2 中处理这个问题?我发现的所有内容都说使用 shell 脚本来处理它,但在需要时复制和移动到新服务器并不那么容易。
截至目前,我的 cron 作业只是 运行 在一个永无止境的 while 循环(除非出现错误)中运行,最后最多等待 5 秒。如果出错,它会退出并报告错误,然后重新启动,因为它正在通过 pm2 运行ning。不过,我对这个实现并不太兴奋。还有其他选择吗?
编辑以澄清我当前的逻辑 -
function runScript() {
while (!err) {
// do stuff
wait(5 seconds - however long 'do stuff' took) // if it took 1 second to 'do stuff', then it waits 4 seconds
}
}
runScript()
这感觉像是一种绕过 pm2 的 cron 限制的 hacky 方法。有可能我只是偏执狂...我只是想确保我没有使用反模式。
您在 while 循环中执行 cron 作业 运行 是什么意思? 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 秒间隔执行此操作,但仅当方法不是 运行ning 时,只需在等式中添加一个跟踪变量,例如:
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 调用,但变量的想法保持不变。
要在您的操作结束之间正好有 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);