I'm specificaly using AnyEvent::Inotify::Simple (using EV as backend) to monitor file events. So I have a handler callback that in a particular case, I need to "pause" before continuing. sleep
obviously halts everything (so other events don't get handled until after sleep
is done), so I tried using alarm
however if the same scenario occurs that sets the alarm again, the original alarm (and therefore its $SIG{ALRM}
sub) is ignored and only the "new" one is run.
#sleep-based approach (definitely a no-go)
sub handler {
my ( $self, $event, $file ) = @_;
#do some stuff
...
if( $some_condition_exists ) {
sleep(3);
#now that we've waited, if some change occurred then do stuff
if ( $new_change_occurred ) {
#do some new stuff
}
}
return;
}
#alarm -based approach (still a no-go when callback is called again while original alarm is still counting down)
sub handler {
my ( $self, $event, $file ) = @_;
#do some stuff
...
if( $some_condition_exists ) {
$SIG{ALRM} = sub {
#now that we've waited, if some change occurred then do stuff
if ( $new_change_occurred ) {
#do some new stuff
}
}
alarm(3);
}
return;
}
Any advice would be appreciated? All I need is a way to make the callback pause while continuing to handle new inotify events asynchronously.
When using an AnyEvent::timer, make sure you keep track of the guard object it returns. I typically store them in a global.
If you assign it to a variable that goes out of scope, the timer will be canceled.
my $guards;
sub handler {
my ( $self, $event, $file ) = @_;
#do some stuff
...
if( $some_condition_exists ) {
$guards->{$file} = AE::timer 3,0,sub {
#now that we've waited, if some change occurred then do stuff
if ( $new_change_occurred ) {
#do some new stuff
}
};
}
return;
}