Author image Chris Drake

NAME

IO::BufferedSelect2 - Line-buffered select interface with stream-reading facility

SYNOPSIS

    use IO::BufferedSelect2;
    my $bs = new IO::BufferedSelect2( { $fn1 => $fh1, $fn2 => $fh2 });
    # $fn1 is the filename. $fh1 is the already-opened filehandle of $fn1
    while(1)
    {
        my @ready = $bs->read_line(1);  # blocks if no data on any files
        my $more=0;
        foreach(@ready)
        {
            my ($fh, $line) = @$_;
            my $fh_name = ($fh == $fh1 ? "fh1" : "fh2");
            if(defined($line)) {
              print "$fh_name: $line"; $more++;
            } else {
              print "$fh_name (hit EOF - waiting for more lines to arrive)\n";
            }
        }
        if(!$more) { print "Hit end on all - you can exit here if you don't expect the input files to grow\n"; }
    }

DEPENDENCIES

Linux::Inotify2;

DESCRIPTION

Update of IO::BufferedSelect supporting "tail -f" facility (ability to read from files which might be growing, like logs etc). Uses Linux::Inotify2

The perl select and linux inotify system calls allow us to process multiple streams simultaneously, blocking until one or more of them is ready for reading or writing or when EOF is hit. Unfortunately, this requires us to use sysread and syswrite rather than Perl's buffered I/O functions. In the case of reading, there are three issues with combining select with readline: (1) select might block but the data we want is already in Perl's input buffer, ready to be slurped in by readline; (2) select might indicate that data is available, but readline will block because there isn't a full $/-terminated line available; and (3) select might not block (thus preventing us from sleeping), even though there is no data to read (e.g. at EOF, the end of a file, even if the file might be extended later)

The purpose of this module is to implement a buffered version of the select interface that operates on lines, rather than characters. Given a set of filehandles, it will block until a full line is available on one or more of them.

Note that this module is currently limited, in that it only does select for readability, not writability or exceptions. $/ is the line separator.

CONSTRUCTOR

new ( HANDLES )

Create a BufferedSelect2 object for a set of filename+filehandle pairs. Note that because this class buffers input from these filehandles internally, you should only use the BufferedSelect2 object for reading from them (you shouldn't read from them directly or pass them to other BufferedSelect2 instances).

METHODS

read_line
read_line ($blocking)
read_line ($blocking, %handles)

Block until a line is available on one of the filehandles. If $blocking is undef, it blocks indefinitely; otherwise, it returns only when new data becomes available.

If %handles is specified, then only these filehandles will be considered; otherwise, it will use all filehandles passed to the constructor.

Returns a list of pairs [$fh, $line], where $fh is a filehandle and $line is the line that was read (including the newline, ala readline). If the filehandle reached EOF, one $line of undef will return; but you may keep reading from this $fh; as soon as more data arrives, $line will again return it (and in future another undef when EOF is again reached, etc.)

SEE ALSO

IO::Select IO::BufferedSelect

AUTHOR

Chris Drake, <cdrake@cpan.org>

COPYRIGHT AND LICENSE

IO::BufferedSelect2 Copyright (C) 2021 by Chris Drake IO::BufferedSelect Copyright (C) 2007 by Antal Novak

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.