【问题标题】:Restart a Perl Script on Error? (Perl Newbie)出错时重新启动 Perl 脚本? (Perl 新手)
【发布时间】:2011-12-04 20:57:36
【问题描述】:

我正在使用从 CPAN 获得的 AnyEvent::Twitter::Stream 模块。我也是 Perl 的新手,我从示例中修改的这个脚本会触发一个事件,一旦基于某些条件从 Twitter 流 API 读取一条推文,就会将一些推特数据插入数据库。我已经编辑了一些代码,但一般信息如下:

#!/usr/bin/perl
    use strict;
    use AnyEvent::Twitter::Stream;

    use DBI;
    use DBD::mysql;



    my $done = AnyEvent->condvar;

    my($user, $password, $method, $args) = @ARGV;
    # my twitter login
    my %args;
    if ($method eq 'follow') {
        $args{follow} = $args;
        $method = 'filter';
    } elsif ($method eq 'track') {
        $args{track}  = $args;
        $method = 'filter';
    }

    binmode STDOUT, ":utf8";

    my $streamer = AnyEvent::Twitter::Stream->new(
        username => $user,
        password => $password,
        timeout => 0,
        method   => $method || "sample",
        %args,
        on_keepalive => sub {
              warn "ping\n";
          },
        on_tweet => sub {

            my $DBIconnect;
            #db connection info

            my $dsn = "dbi:mysql:$database:$host:$dbport";

            $DBIconnect = DBI->connect($dsn, $db_user, $db_pass);

            my $tweet = shift;

            if($tweet->{id}) {
               # occasionally twitter 
               # insert some data here

                my $save_tweet = $query;
                #print $query;
                my $save_handle = $DBIconnect->prepare($save_tweet);

                if($save_handle->execute()) { 
                    #print "Tweet #" . $tweet->{id} . " Stored\n";
                } else { 
                    #print "Error Saving Tweet #" . $tweet->{id} . "\n";
                }
                $save_handle->finish();
                $DBIconnect->disconnect();
            } else { 
                #print "Tweet did not contain Tweet ID.\n";
            }

        },
        on_error => sub {
            my $error = shift;
            print "Error! Error!";
            warn "ERROR: $error";


            $done->send;
            sleep 2;

            $done->recv;
        },
        on_eof   => sub {
            $done->send;
        },
    );


    $done->recv;

在这个过程中,有时流或应用程序会退出,原因仍然让我感到困惑。我想简单地等待 3 秒钟,然后重新启动整个 perl 脚本(或只是 AnyEvent 实例)以继续读取数据。

你可能会注意到我尝试这样做:

    on_error => sub {
        my $error = shift;
        print "Error! Error!";
        warn "ERROR: $error";


        $done->send;
        sleep 2;

        $done->recv;
    },

这似乎不会重新启动该过程。谁能告诉我这需要什么?

【问题讨论】:

    标签: perl error-handling twitter-streaming-api


    【解决方案1】:

    我不熟悉该模块,但您需要更清楚地了解“流或应用程序将因仍然让我感到困惑的原因而退出”的含义。剧本会死吗?

    如果是这样,捕获错误并重新启动的一种方法是将整个代码包装在 eval 中,如下所示:

    my $continue = 1;
    while ($continue) {
       eval {  # Catch "die" event
           my $streamer = xxx
           # some other call to start the streamer???
       };
       if ($@ =~ /specific error message substring you wish to restart on/) {
           # Do some prep work if needed
       } else {
           $continue = 0; # quit on next loop iteration
           # As alternative to using $continue flag, just do:
           # last; 
       }
    }
    

    【讨论】:

    • 当 on_error 事件被调用时,perl 脚本将退出(停止接收)。您的解决方案似乎通常涵盖了根本问题,即流模块基本上说 ERROR: (这是我想要捕获的)然后退出。我想我不在 PHP 中使用 eval。谢谢!
    • @Zack - eval 在其块形式(谷歌“perldoc eval”)中捕获DIE 信号,因此任何从该模块内执行错误处理的die 语句都会 - 而不是崩溃您的脚本 - 只需退出 eval 并将 die 错误消息内容设置为 $@
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2014-12-09
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多