0

We have a while(1) script that loops through its' various workings, then sleeps for 60 seconds and then goes through it all again. This script needs to run 24/7.

As we add new functionality within the while(1) loop, or just over the course of random issues, sometimes they fail and unfortunately crash the entire script. The solution has been wrapping any such functions in eval{}, but my question is...Is there anyway to globally set that all errors or fatals do NOT halt/kill the entire script so we don't have to wrap everything around the eval{} ?

4

3 回答 3

3

这是没有意义的。程序如何知道从哪里恢复?您必须告诉它在哪里,然后使用eval.

您肯定会更好地为记录失败并重新启动脚本的脚本编写一个包装器。

于 2013-09-05T14:32:49.267 回答
3

你试图做的——忽略任何错误,不惜一切代价继续——是一种非常有问题的做法,可能会使你的程序进入未定义状态,并使实际的错误更难找到。

理论上,您可以覆盖CORE::GLOBAL::die子例程以从您的 Perl 代码中捕获异常,但是一个 realdie仍然可以用作CORE::die子,并且这不会捕获来自 XS 代码或 perl 本身的错误(与 using 不同eval)。请注意,某些模块使用dieandwarn来控制流。考虑以下代码:

sub foo {
  my ($x, $y) = @_;
  croak "X must be smaller than Y" unless $x < $y;
  return $y - $x;
}

现在如果die变成 a warn,那么该函数可能开始输出负数,造成各种破坏(例如,当用于数组索引时)。

继续使用eval解决方案,甚至更好:迁移到Try::Tiny. 致命错误的存在是有原因的。


如果需要高可靠性,您可能希望采用类似 Erlang 的模型:工作进程池。如果出现错误,则终止该进程,并启动替换进程。

于 2013-09-05T14:33:05.520 回答
2

尽管有其他答案,但事实是某些错误可能不容易恢复,只是忽略它们并拖着走很容易导致不良行为。另一种选择是删除while循环,以便脚本只执行一次,然后从 调用它cron,这样您就可以按计划运行程序。例如,您可能会打开一个 shell 并调用crontab -e以编辑调度程序并添加以下行:

* * * * * perl /path/to/script.pl

它将每分钟运行一次你的脚本,如果有任何输出,包括警告和错误,就会向你发送一封邮件。

于 2013-09-05T14:53:04.707 回答