Smartelf
Smartelf

Reputation: 879

perl event loop with multiple blocking watchers?

I am trying to figure out Event Loops in Perl?

Currently my program does something like this:

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

where wait_for_event is blocking.

I am trying to figure out if I can use EV, or AnyEvent(AE), or something else to add another event watcher.

for example, I want to be able to call try_to_do_something() every 2 seconds, but am currently stuck putting it into the event loop.

Also, I would like to add some form of interaction with the program, possibly through sockets(another watcher).

Thanks

Upvotes: 2

Views: 1493

Answers (2)

Sebastian Stumpf
Sebastian Stumpf

Reputation: 2791

Maybe you are trying to do something like this?

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;

This snippet with AnyEvent and AnyEvent::Filesys::Notify is just one way to do it. Basically it's almost always the same way, regardless of your framework: Setup your watchers with your callbacks and enter your "mainloop".

Upvotes: 1

LeoNerd
LeoNerd

Reputation: 8532

The idea with event systems is not to write linear code that blocks waiting on one specific event, but instead to set up handlers for what to do when events happen, then wait for any of these events to happen. The event frameworks will generally dispatch to these event handlers when the events happen. The trick then is to set up the handlers, and wait on it.

Both EV and AnyEvent will support that sort of thing. Also things to look at are POE, IO::Async and Reflex.

The general idea will be much the same in any of these, but I shall give an example in IO::Async as I know it the best, mostly because I wrote it.

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;

The $loop->add method installs a notifier object into the loop, which in this case is a periodic timer that every 2 seconds runs the specified function. At the bottom of the program the main $loop->run method then dispatches to event handlers at the appropriate times.

Upvotes: 5

Related Questions