| IO::Async - a collection of modules that implement asynchronous filehandle IO |
IO::Async - a collection of modules that implement asynchronous filehandle
IO
use IO::Async::Stream; use IO::Async::Loop;
use Socket qw( SOCK_STREAM );
my $loop = IO::Async::Loop->new();
$loop->connect(
host => "some.other.host",
service => 12345,
socktype => SOCK_STREAM,
on_connected => sub {
my ( $socket ) = @_;
my $stream = IO::Async::Stream->new(
handle => $socket,
on_read => sub {
my ( $self, $buffref, $closed ) = @_;
return 0 unless( $buffref =~ s/^(.*\n)// );
print "Received a line $1";
return 1;
}
);
$stream->write( "An initial line here\n" );
$loop->add( $stream );
},
...
);
$loop->loop_forever();
This collection of modules allows programs to be written that perform
asynchronous filehandle IO operations. A typical program using them would
consist of a single subclass of IO::Async::Loop to act as a container o
other objects, which perform the actual IO work required by the program. As
as IO handles, the loop also supports timers and signal handlers, and
includes more higher-level functionallity built on top of these basic parts.
Because there are a lot of classes in this collection, the following overview gives a brief description of each.
A the IO::Async::Handle manpage object represents a single IO handle that is being
managed. While in most cases it will represent a single filehandle, such as a
socket (for example, an IO::Socket::INET connection), it is possible to
have separate reading and writing handles (most likely for a program's
STDIN and STDOUT streams, or a pair of pipes connected to a child
process).
The the IO::Async::Stream manpage class is a subclass of IO::Async::Handle which
maintains internal incoming and outgoing data buffers. In this way, it
implements bidirectional buffering of a byte stream, such as a TCP socket. The
class automatically handles reading of incoming data into the incoming buffer,
and writing of the outgoing buffer. Methods or callbacks are used to inform
when new incoming data is available, or when the outgoing buffer is empty.
Both of the above are subclasses of the IO::Async::Notifier manpage, which does not
perform any IO operations itself, but instead acts to coordinate a collection
of other Notifiers, or act as a base class to build the specific IO
functionallity upon. For other types of Notifier, see Timers and Signals
below.
The the IO::Async::Loop manpage object class represents an abstract collection of
IO::Async::Notifier objects, filehandle IO watches, timers, signal
handlers, and other functionallity. It performs all of the abstract
collection management tasks, and leaves the actual OS interactions to a
particular subclass for the purpose.
the IO::Async::Loop::IO_Poll manpage uses an IO::Poll object for this test.
the IO::Async::Loop::Select manpage uses the select() syscall.
Other subclasses of loop may appear on CPAN under their own dists; such
as the IO::Async::Loop::Glib manpage which acts as a proxy for the Glib::MainLoop of
a Glib-based program, or the IO::Async::Loop::IO_Ppoll manpage which uses the
the IO::Ppoll manpage object to handle signals safely on Linux.
As well as these general-purpose classes, the IO::Async::Loop constructor
also supports looking for OS-specific subclasses, in case a more efficient
implementation exists for the specific OS it runs on.
The IO::Async::Loop object provides a number of methods to facilitate the
running of child processes. spawn_child is primarily a wrapper around the
typical fork()/exec() style of starting child processes, open_child
builds on this to provide management of child process file handles and streams
connected to them, and finally run_child builds on that to provide a method
similar to perl's readpipe() (which is used to implement backticks ``).
The IO::Async framework generally provides mechanisms for multiplexing IO
tasks between different handles, so there aren't many occasions when it is
necessary to run code in another thread or process. Two cases where this does
become useful are when:
A large amount of computationally-intensive work needs to be performed.
An OS or library-level function needs to be called, that will block, and no asynchronous version is supplied.
For these cases, an instance of the IO::Async::DetachedCode manpage can be used around a code block, to execute it in a detached child process. The code in the sub-process runs isolated from the main program, communicating only by function call arguments and return values.
A the IO::Async::Timer manpage object represents a counttime timer, which will invoke a callback after a given delay. It can be stopped and restarted.
The the IO::Async::Loop manpage also supports methods for managing timed events on a lower level. Events may be absolute, or relative in time to the time they are installed.
A the IO::Async::Signal manpage object represents a POSIX signal, which will invoke a callback when the given signal is received by the process. Multiple objects watching the same signal can be used; they will all invoke in no particular order.
The the IO::Async::MergePoint manpage object class allows for a program to wait on the completion of multiple seperate subtasks. It allows for each subtask to return some data, which will be collected and given to the callback provided to the merge point, which is called when every subtask has completed.
The IO::Async::Loop provides several methods for performing network-based
tasks. Primarily, the connect and listen methods allow the creation of
client or server network sockets. Additionally, the resolve method allows
the use of the system's name resolvers in an asynchronous way, to resolve
names into addresses, or vice versa.
This collection of modules is still very much in development. As a result, some of the potentially-useful parts or features currently missing are:
A IO::Async::Loop subclass to perform integration with Event. Consider
further ideas on Solaris' ports, BSD's Kevents and anything that might
be useful on Win32.
A consideration on how to provide per-OS versions of the utility classes. For
example, Win32 would probably need an extensively-different ChildManager,
or OSes may have specific ways to perform asynchronous name resolution
operations better than the generic DetachedCode approach. This should be
easier to implement now that the IO::Async::Loop magic constructor looks
for OS-specific subclasses first.
A consideration of whether it is useful and possible to provide integration with POE or AnyEvent.
Event - Event loop processing
POE - portable multitasking and networking framework for Perl
Paul Evans <leonerd@leonerd.org.uk>
| IO::Async - a collection of modules that implement asynchronous filehandle IO |