AnyEvent-Filesys-Notify

 view release on metacpan or  search on metacpan

lib/AnyEvent/Filesys/Notify/Role/KQueue.pm  view on Meta::CPAN

package AnyEvent::Filesys::Notify::Role::KQueue;

# ABSTRACT: Use IO::KQueue to watch for changed files

use Moo::Role;
use MooX::late;
use namespace::autoclean;
use AnyEvent;
use IO::KQueue;
use Carp;

our $VERSION = '1.23';

# Arbitrary limit on open filehandles before issuing a warning
our $WARN_FILEHANDLE_LIMIT = 50;

sub _init {
    my $self = shift;

    my $kqueue = IO::KQueue->new()
      or croak "Unable to create new IO::KQueue object";
    $self->_fs_monitor($kqueue);

    # Need to add all the subdirs to the watch list, this will catch
    # modifications to files too.
    my $old_fs = $self->_old_fs;
    my @paths  = keys %$old_fs;

    # Add each file and each directory to a hash of path => fh
    my $fhs = {};
    for my $path (@paths) {
        my $fh = $self->_watch($path);
        $fhs->{$path} = $fh if defined $fh;
    }

    # Now use AE to watch the KQueue
    my $w;
    $w = AE::io $$kqueue, 0, sub {
        if ( my @events = $kqueue->kevent ) {
            $self->_process_events(@events);
        }
    };
    $self->_watcher( { fhs => $fhs, w => $w } );

    $self->_check_filehandle_count;
    return 1;
}

# Need to add newly created items (directories and files) or remove deleted
# items.  This isn't going to be perfect. If the path is not canonical then we
# won't deleted it.  This is done after filtering. So entire dirs can be
# ignored efficiently.
sub _post_process_events {
    my ( $self, @events ) = @_;

    for my $event (@events) {
        if ( $event->is_created ) {
            my $fh = $self->_watch( $event->path );
            $self->_watcher->{fhs}->{ $event->path } = $fh if defined $fh;
        } elsif ( $event->is_deleted ) {
            delete $self->_watcher->{fhs}->{ $event->path };
        }
    }

    $self->_check_filehandle_count;
    return;
}



( run in 0.682 second using v1.01-cache-2.11-cpan-39bf76dae61 )