如何捕获Perl MongoDB :: Cursor的'recv timed out'错误?

时间:2012-12-05 02:10:04

标签: perl mongodb

我有一个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->找到(...)的eval块
  • 围绕$ cursor-> next()的eval块
  • 连接query_timeout值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(); };
    
  • 2 个答案:

    答案 0 :(得分:1)

    这可能是一个退出电话,而不是一个diie,所以它不能被eval捕获。试试Test :: Trap。

      

    主要(但不是唯一)用于测试脚本:类固醇的块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';
      }
    

    答案 1 :(得分:1)

    幸运的是,它是die,您可以捕获它。一旦我写了一个AnyEvent + EV守护进程,通过这个肮脏的伎俩重新生成来欺骗死亡(邪恶的笑):

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

    brian d foy在他的Override die with END or CORE::GLOBAL::die文章中描述了一个普遍的die陷阱:

    $SIG{__DIE__} = sub { warn "I'm sorry, Dave, I'm afraid I can't do that" };