bucle de eventos perl con múltiples observadores de bloqueo?

¿Estoy tratando de averiguar los bucles de eventos en Perl?

Actualmente mi programa hace algo como esto:

    while(my $event = wait_for_event()){
        handle_event($event);
        try_to_do_something();
    }

donde wait_for_event está bloqueando.

Estoy tratando de averiguar si puedo usar EV, AnyEvent (AE) o algo más para agregar otro observador de eventos.

por ejemplo, quiero poder llamar a try_to_do_something() cada 2 segundos, pero actualmente estoy atascado poniéndolo en el bucle de eventos.

Además, me gustaría agregar alguna forma de interacción con el programa, posiblemente a través de sockets (otro observador).

Muchas Gracias

preguntado el 22 de mayo de 12 a las 20:05

2 Respuestas

La idea con los sistemas de eventos no es escribir código lineal que bloquee la espera de un evento específico, sino configurar controladores para saber qué hacer cuando suceden los eventos y luego esperar a que suceda cualquiera de estos eventos. Los marcos de eventos generalmente se envían a estos controladores de eventos cuando ocurren los eventos. El truco entonces es configurar los controladores y esperar.

Tanto EV como AnyEvent admitirán ese tipo de cosas. También las cosas para mirar son POE, IO::Async y Reflex.

La idea general será muy similar en cualquiera de estos, pero daré un ejemplo en IO::Async como lo conozco mejor, sobre todo porque yo lo escribí.

use IO::Async::Loop;
use IO::Async::Timer::Periodic;

my $loop = IO::Async::Loop->new;

$loop->add( IO::Async::Timer::Periodic->new(
    interval => 2,
    on_tick => \&try_to_do_something
)->start );

# Perhaps here you'd add your socket watcher, using an
# IO::Async::Handle or ::Stream or something else

$loop->run;

La $loop->add El método instala un objeto notificador en el bucle, que en este caso es un temporizador periódico que cada 2 segundos ejecuta la función especificada. En la parte inferior del programa, el principal $loop->run El método luego se envía a los controladores de eventos en los momentos apropiados.

contestado el 22 de mayo de 12 a las 22:05

Actualmente estoy usando File::ChangeNotify, no estoy seguro de cómo agregar ese observador a cualquiera de los controladores de eventos anteriores. Gracias - inteligente

¿Quizás estás tratando de hacer algo como esto?

use AnyEvent;
use AnyEvent::Filesys::Notify;

sub try_to_do_something { say "every two seconds" }
sub handle_event { say $_->path." ".$_->type for @_ }

my $n = AnyEvent::Filesys::Notify->new(
    dirs => ['/tmp'],
    interval => 0.5,
    filter => sub { 1 },
    cb => sub { handle_event(@_) },
);
my $w = AE::timer 0, 2, sub {try_to_do_something};

AnyEvent->condvar->recv;

Este fragmento con AnyEvent y AnyEvent::Filesys::Notify es solo una forma de hacerlo. Básicamente, es casi siempre de la misma manera, independientemente de su marco: configure sus observadores con sus devoluciones de llamada e ingrese su "bucle principal".

contestado el 23 de mayo de 12 a las 06:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.