Перезапустить Perl-скрипт при ошибке? (Новичок в Perl)

#perl #error-handling #twitter-streaming-api

#perl #обработка ошибок #twitter-streaming-api

Вопрос:

Я использую модуль AnyEvent ::Twitter::Stream, полученный из CPAN. Я также новичок в Perl, и этот скрипт, который я модифицировал из примера, запускает событие для вставки части данных Twitter в базу данных, как только твит считывается из потокового API Twitter на основе некоторых условий. Я отредактировал часть кода, но общая информация приведена ниже:

 #!/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 "pingn";
          },
        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} . " Storedn";
                } 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;
    },
  

Похоже, это не перезапускает процесс. Может ли кто-нибудь дать мне представление о том, что для этого потребуется?

Ответ №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; 
   }
}
  

Комментарии:

1. Сценарий perl завершит работу (прекратит прием) при вызове события on_error . Ваше решение, похоже, в целом охватывает основную проблему, которая заключается в том, что модуль потоковой передачи в основном сообщает ERROR: (что я и хочу поймать), а затем завершает работу. Думаю, я не использую evals в PHP. Спасибо!

2. @Zack — eval в своей блочной форме (google «perldoc eval») перехватывает DIE сигнал, поэтому любой die оператор, который выполняет обработку ошибок из этого модуля, вместо сбоя вашего скрипта просто завершит eval работу и установит содержимое сообщения об ошибке die $@ .