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 )