App-Inotify-Hookable

 view release on metacpan or  search on metacpan

lib/App/Inotify/Hookable.pm  view on Meta::CPAN

    $self->log(
        "Starting up, " .
        (@watch_dirs ?
            ($self->recursive ? "recursively" : "non-recursively") .
            " " .
            "watching directories <@watch_dirs>" .
            (@watch_files ? " and " : "")
        : "") .
        (@watch_files ?
            "watching files <@watch_files>"
        : "")
    );

    my $notifier = $self->_notifier;
    $self->setup_watch;
    my $buffer_time = $self->buffer_time;
    while (my @events = $notifier->read()) {
        # At this point we have an event, but Linux sends these *really
        # fast* so if someone does "touch foo bar zar" we might only get
        # an event for the first file, then later the rest.
        #
        # So buffer up events for $sleep_ms and see if we stop getting
        # them, then restart.
        my $sleep_ms = $buffer_time;
        my $sleep_us = $sleep_ms * 10**3;

        my %modified_paths;

        my $log_modified_paths = sub {
            my $events = shift;
            for my $event (@$events) {
                my $fullname = $event->fullname;
                $fullname =~ s[//][/]g; # We have double slashes for some reason

                my $ignore_path = 0;

                IGNORE_PATHS: foreach my $re ($self->ignore_paths) {
                    if ($fullname =~ m{(?:/|^)$re}) {
                        $ignore_path = 1;
                        last IGNORE_PATHS;
                    }
                }

                $modified_paths{$fullname} = undef if not $ignore_path;
            }
            return;
        };

      WAIT: while (1) {
            for my $event (@events) {
                $self->log("EVENT: " . $dumper_squashed->({
                    cookie => $event->cookie,
                    fullname => $event->fullname,
                    mask => $self->_bitmask->explain_mask($event->mask),
                })) if $self->debug;
            }
            $log_modified_paths->(\@events);
            @events = ();
            try {
                local $SIG{ALRM} = sub {
                    die "Timeout waiting for ->read";
                };
                ualarm($sleep_us);
                @events = $notifier->read;
                ualarm(0);
            } catch {
                $self->log("We have no more events with a timeout of $sleep_ms ms") if $self->debug;
            };

            if (@events) {
                $self->log("We have events, waiting another $sleep_ms ms and checking again") if $self->debug;

                $log_modified_paths->(\@events);
            } else {
                # No more events
                last WAIT;
            }
        }

        if (keys %modified_paths) {
            $self->log("Had changes in your paths");

            if (keys %{ $self->on_modify_path_command }) {
                $self->log("Checking for path-specific hooks") if $self->debug;
                my %hooks_to_run;
                my $on_modify_path_command = $self->on_modify_path_command;
                for my $path (keys %modified_paths) {
                    for my $path_hook (keys %$on_modify_path_command) {
                        $hooks_to_run{$path_hook} = 1
                            if $path =~ /$path_hook/;
                    }
                }
                if (keys %hooks_to_run) {
                    $self->log("Running path-specific hooks");
                    my $t0 = [gettimeofday];
                    for my $hook_to_run (keys %hooks_to_run) {
                        my $command = $on_modify_path_command->{$hook_to_run};
                        $self->log("Running path hook <$hook_to_run>: <$command>");
                        system $command;
                    }
                    my $elapsed = tv_interval ( $t0 );
                    $self->log(sprintf "FINISHED running path-specific hooks. Took %.2fs", $elapsed);
                }
            }

            if (my @commands = $self->on_modify_command) {
                $self->log("Running global hooks");
                my $t0 = [gettimeofday];
                for my $command (@commands) {
                    $self->log("Running <$command>");
                    system $command;
                }
                my $elapsed = tv_interval ( $t0 );
                $self->log(sprintf "FINISHED on-modify command. Took %.2fs", $elapsed);
            }
        }

        # Re-setup the watching if needed, we may have new directories.
        $self->setup_watch;
    }

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.513 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )