1

私は特に AnyEvent::Inotify::Simple (バックエンドとして EV を使用) を使用してファイル イベントを監視しています。したがって、特定のケースでは、続行する前に「一時停止」する必要があるハンドラー コールバックがあります。 sleep明らかにすべてを停止します(そのため、他のイベントは処理が完了するまで処理されませんsleep)ので、使用してみalarmましたが、アラームを再度設定する同じシナリオが発生した場合、元のアラーム(したがってその$SIG{ALRM}サブ)は無視され、「新しい" 1 つが実行されます。

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

アドバイスをいただければ幸いです。必要なのは、新しい inotify イベントを非同期で処理し続けながら、コールバックを一時停止する方法だけです。

4

1 に答える 1

1

AnyEvent::timer を使用する場合は、それが返すガード オブジェクトを追跡するようにしてください。私は通常、それらをグローバルに保存します。

スコープ外になる変数に代入すると、タイマーがキャンセルされます。

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;
}
于 2015-05-04T17:37:55.497 に答える