3

我有一个 Perl 程序通过 cron 发出这些消息:

recv timed out (60000 ms) at /usr/local/lib/perl/5.8.8/MongoDB/Cursor.pm line 251.
recv timed out (60000 ms) at /usr/local/lib/perl/5.8.8/MongoDB/Cursor.pm line 251.
recv timed out (60000 ms) at /usr/local/lib/perl/5.8.8/MongoDB/Cursor.pm line 251.

我已采取以下步骤来缓解:

  • $collection->find(...) 周围的 eval 块
  • $cursor->next() 周围的 eval 块
  • 连接查询超时值 60000
  • 连接超时 1000

    超时并不奇怪,因为服务器处于高负载状态。但我想巧妙地捕捉超时并优雅地退出。

    有什么建议么?

    更新:

    我已经确定 recv 超时肯定发生在$cursor->next()调用上。

    # doesn't capture
    {   
        local $SIG{__DIE__} = sub { return; };    
        $doc_ref = $cursor->next();
    };
    
    # doesn't capture
    eval { $doc_ref = $cursor->next(); };
    
  • 4

    2 回答 2

    1

    幸运的是,它是一个die,您可以捕获它。有一次我写了一个AnyEvent + EV守护程序,它通过这个肮脏的技巧重生来欺骗死亡(邪恶的笑声):

    use FindBin qw($Script);
    use EV;
    $EV::DIED = sub { warn $@; exec $^X, $Script, qw(restart) };
    

    还有一个通用die陷阱,由 brian d foy 在他的Override die with END or CORE::GLOBAL::die文章中描述:

    $SIG{__DIE__} = sub { warn "I'm sorry, Dave, I'm afraid I can't do that" };
    
    于 2012-12-05T13:31:00.683 回答
    1

    它可能是进行退出调用,而不是 diie,因此 eval 无法捕获它。尝试测试::陷阱。

    主要(但不限于)用于测试脚本: 类固醇上的块 eval,可配置和可扩展,但默认情况下捕获 (Perl) STDOUT、STDERR、警告、异常、可能的退出代码和来自盒装块的返回值测试代码。

      use Test::Trap;
    
      my @r = trap { some_code(@some_parameters) };
      if ( $trap->exit != 0 ){
        say 'Expecting &some_code to exit with not 0';
      }
    
    于 2012-12-05T10:41:15.810 回答