1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
NAME
"IO::Async" - perform asynchronous filehandle IO and other operations
SYNOPSIS
use IO::Async::Stream;
use IO::Async::Loop;
my $loop = IO::Async::Loop->new();
$loop->connect(
host => "some.other.host",
service => 12345,
socktype => '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();
DESCRIPTION
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 of other objects, which perform the actual IO work required by
the program. As well 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.
Notifiers
The base class of all the event handling subclasses is
IO::Async::Notifier. It does not perform any IO operations itself, but
instead acts as a base class to build the specific IO functionallity
upon. It can also coordinate a collection of other Notifiers contained
within it, forming a tree structure.
The following sections describe particular types of Notifier.
File Handle IO
An IO::Async::Handle object is a Notifier that represents a single IO
handle 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 IO::Async::Stream 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.
The IO::Async::Listener class is another subclass of IO::Async::Handle
which facilitates the use of "listen()"-mode sockets. When a new
connection is available on the socket it will "accept()" it and pass the
new client socket to its callback function.
Timers
An IO::Async::Timer::Countdown object represents a count time timer,
which will invoke a callback after a given delay. It can be stopped and
restarted.
An IO::Async::Timer::Periodic object invokes a callback at regular
intervals from its initial start time. It is reliable and will not drift
due to the time taken to run the callback.
The IO::Async::Loop 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.
Signals
An IO::Async::Signal 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.
Merge Points
The IO::Async::MergePoint 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.
Loops
The IO::Async::Loop object class represents an abstract collection of
IO::Async::Notifier objects, and manages the actual filehandle IO
watchers, 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.
IO::Async::Loop::Poll uses an IO::Poll object for this test.
IO::Async::Loop::Select uses the "select()" syscall.
Other subclasses of loop may appear on CPAN under their own dists; such
as IO::Async::Loop::Glib which acts as a proxy for the "Glib::MainLoop"
of a Glib-based program, or IO::Async::Loop::Ppoll which uses the
IO::Ppoll 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.
Child Processes
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 ``).
Detached Code
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 IO::Async::DetachedCode 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.
Networking
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.
TODO
This collection of modules is still very much in development. As a
result, some of the potentially-useful parts or features currently
missing are:
* An 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.
SEE ALSO
* Event - Event loop processing
* POE - portable multitasking and networking framework for Perl
AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
|