简体   繁体   中英

How do you “sleep” in an AnyEvent callback without pausing the whole script?

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM