[Moscow.pm] AnyEvent и die

Mons Anderson inthrax на gmail.com
Ср Дек 8 09:26:37 PST 2010


On Tuesday 07 December 2010 17:42:40 Ruslan Zakirov wrote:
> Привет,
>
> EV: error in callback (ignoring): booo at XXX.pm line 88
>
> Я не знаю, что с этим делать. Я еще не разбирался в документации всех
> модулей, но не вижу разумного решения. Есть EV::DIED, ок, но контекст
> потерялся и объекты какие-то уже ушли. Опять же эта функция единая для
> всех событий и local здесь не поможет.
>
> У меня в одном сервере и веб интерфейс на AnyEvent::HTTPD и
> мониторинг. Получается, что если я из веб интерфейса запустил что-то и
> жду события, то смерть приводит к тому, что пользователь сидит и ждет
> пока браузер просрется, но он не просирается.
>
> Что вы делаете с ошибками? Везде eval расставляете или что-то еще?
> Хотя не вижу как eval может особо помочь.

Мой подход:
Every callback must be called ;)

у меня паттерн

... cb => sub {
	if (shift) { success(); }
        else       { warn "failure: @_"; }
        # или
        defined( my $x = shift ) or return failure(@_);
        ...
}

и в обработчике

sub { 
...
   eval { ... ; 1 } or return $args{cb}(undef, $@);
...
}


В тестах/девелопменте удобно юзать Impl::Perl: там die "убивает" приложение, 
как ему и положено.


еще когда-то делал такую штуку для Object::Event:

        $self->set_exception_cb( sub {
                my ($e, $event, @args) = @_;
                my $con;
                {
                        local $::self = $self;
                        local $::con;
                        local $::event = $event;
                        {
                                package DB;
                                my $i = 0;
                                while (my @c = caller(++$i)) {
                                        #warn "$i. [@DB::args]";
                                        next if @DB::args < 1;
                                        last if $DB::args[0] == $::self and 
$DB::args[1] eq $::event;
                                }
                                $::con = $DB::args[2];
                        }
                        $con = $::con;
                }
                if ($con) {
                        my $msg = "INTERNAL ERROR";
                        if ($self->{devel}) {
                                $e =~ s{(?:\r?\n)+}{ }sg;
                                $e =~ s{\s+$}{}s;
                                $msg .= ": ".$e;
                        }
                        $con->reply($msg);
                }
                warn "exception during $event : $e";
        } );





-- 
Vladimir Perepelitsa aka Mons Anderson
<inthrax на gmail.com> / #99779956


Подробная информация о списке рассылки Moscow-pm