#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$@
.