POE

 view release on metacpan or  search on metacpan

lib/POE/Wheel/ReadWrite.pm  view on Meta::CPAN


    if ($input eq "quit") {
      $wheel->event( FlushedEvent => "shutdown" );
      $wheel->put("Goodbye.");
    }
    else {
      $wheel->put("Echo: $input");
    }
  }

Here's the shutdown handler.  It just destroys the wheel to end the
connection:

  sub handle_flushed {
    my $wheel_id = $_[ARG0];
    delete $_[HEAP]{wheel}{$wheel_id};
  }

=head4 ErrorEvent

ErrorEvent names the event that a POE::Wheel::ReadWrite object will
emit whenever an error occurs.  Every ErrorEvent includes four
parameters:

C<ARG0> describes what failed, either "read" or "write".  It doesn't
name a particular function since POE::Wheel::ReadWrite delegates
actual reading and writing to a L<POE::Driver> object.

C<ARG1> and C<ARG2> hold numeric and string values for C<$!> at the
time of failure.  Applicatin code cannot test C<$!> directly since its
value may have changed between the time of the error and the time the
error event is dispatched.

C<ARG3> contains the wheel's unique ID.  The wheel's ID is used to
differentiate between many wheels managed by a single session.

ErrorEvent may also indicate EOF on a FileHandle by returning
operation "read" error 0.  For sockets, this means the remote end has
closed the connection.

A sample ErrorEvent handler:

  sub error_state {
    my ($operation, $errnum, $errstr, $id) = @_[ARG0..ARG3];
    if ($operation eq "read" and $errnum == 0) {
      print "EOF from wheel $id\n";
    }
    else {
      warn "Wheel $id encountered $operation error $errnum: $errstr\n";
    }
    delete $_[HEAP]{wheels}{$id}; # shut down that wheel
  }

=head4 HighEvent

HighEvent and LowEvent are used along with HighMark and LowMark to
control the flow of streamed output.

A HighEvent is sent when the output buffer of a POE::Wheel::ReadWrite
object exceeds a certain size (the "high water" mark, or HighMark).
This advises an application to stop streaming output.  POE and Perl
really don't care if the application continues, but it's possible that
the process may run out of memory if a buffer grows without bounds.

A POE::Wheel::ReadWrite object will continue to flush its buffer even
after an application stops streaming data, until the buffer is empty.
Some streaming applications may require the buffer to always be primed
with data, however.  For example, a media server would encounter
stutters if it waited for a FlushedEvent before sending more data.

LowEvent solves the stutter problem.  A POE::Wheel::ReadWrite object
will send a LowEvent when its output buffer drains below a certain
level (the "low water" mark, or LowMark).  This notifies an
application that the buffer is small enough that it may resume
streaming.

The stutter problem is solved because the output buffer never quite
reaches empty.

HighEvent and LowEvent are edge-triggered, not level-triggered.  This
means they are emitted once whenever a POE::Wheel::ReadWrite object's
output buffer crosses the HighMark or LowMark.  If an application
continues to put() data after the HighMark is reached, it will not
cause another HighEvent to be sent.

HighEvent is generally not needed.  The put() method will return the
high watermark state: true if the buffer is at or above the high
watermark, or false if the buffer has room for more data.  Here's a
quick way to prime a POE::Wheel::ReadWrite object's output buffer:

  1 while not $_[HEAP]{readwrite}->put(get_next_data());

POE::Wheel::ReadWrite objects always start in a low-water state.

HighEvent and LowEvent are optional.  Omit them if flow control is not
needed.

=head4 LowEvent

HighEvent and LowEvent are used along with HighMark and LowMark to
control the flow of streamed output.  Please see L</HighEvent> for
more information and examples.

=for comment
TODO - Example here.

=head2 put RECORDS

put() accepts a list of RECORDS, which will be serialized by the
wheel's Filter and buffered and written by its Driver.

put() returns true if a HighMark has been set and the Driver's output
buffer has reached or exceeded the limit.  False is returned if
HighMark has not been set, or if the Driver's buffer is smaller than
that limit.

put()'s return value is purely advisory; an application may continue
buffering data beyond the HighMark---at the risk of exceeding the
process' memory limits.  Do not use C<<1 while not $wheel->put()>>
syntax if HighMark isn't set: the application will fail spectacularly!

=head2 event EVENT_TYPE => EVENT_NAME, ...

event() allows an application to modify the events emitted by a
POE::Wheel::ReadWrite object.  All constructor parameters ending in
"Event" may be changed at run time: L</InputEvent>, L</FlushedEvent>,
L</ErrorEvent>, L</HighEvent>, and L</LowEvent>.

Setting an event to undef will disable the code within the wheel that
generates the event.  So for example, stopping InputEvent will also
stop reading from the filehandle.  L</pause_input> and
L</resume_input> may be a better way to manage input events, however.

=for comment
TODO - Example.



( run in 1.849 second using v1.01-cache-2.11-cpan-f56aa216473 )