1POE::Wheel::ReadWrite(3U)ser Contributed Perl DocumentatiPoOnE::Wheel::ReadWrite(3)
2
3
4

NAME

6       POE::Wheel::ReadWrite - non-blocking buffered I/O mix-in for
7       POE::Session
8

SYNOPSIS

10         #!perl
11
12         use warnings;
13         use strict;
14
15         use IO::Socket::INET;
16         use POE qw(Wheel::ReadWrite);
17
18         POE::Session->create(
19           inline_states => {
20             _start => sub {
21               # Note: IO::Socket::INET will block.  We recommend
22               # POE::Wheel::SocketFactory or POE::Component::Client::TCP if
23               # blocking is contraindicated.
24               $_[HEAP]{client} = POE::Wheel::ReadWrite->new(
25                 Handle => IO::Socket::INET->new(
26                   PeerHost => 'www.yahoo.com',
27                   PeerPort => 80,
28                 ),
29                 InputEvent => 'on_remote_data',
30                 ErrorEvent => 'on_remote_fail',
31               );
32
33               print "Connected.  Sending request...\n";
34               $_[HEAP]{client}->put(
35                 "GET / HTTP/0.9",
36                 "Host: www.yahoo.com",
37                 "",
38               );
39             },
40             on_remote_data => sub {
41               print "Received: $_[ARG0]\n";
42             },
43             on_remote_fail => sub {
44               print "Connection failed or ended.  Shutting down...\n";
45               delete $_[HEAP]{client};
46             },
47           },
48         );
49
50         POE::Kernel->run();
51         exit;
52

DESCRIPTION

54       POE::Wheel::ReadWrite encapsulates a common design pattern: dealing
55       with buffered I/O in a non-blocking, event driven fashion.
56
57       The pattern goes something like this:
58
59       Given a filehandle, watch it for incoming data.  When notified of
60       incoming data, read it, buffer it, and parse it according to some low-
61       level protocol (such as line-by-line).  Generate higher-level "here be
62       lines" events, one per parsed line.
63
64       In the other direction, accept whole chunks of data (such as lines) for
65       output.  Reformat them according to some low-level protocol (such as by
66       adding newlines), and buffer them for output.  Flush the buffered data
67       when the filehandle is ready to transmit it.
68

PUBLIC METHODS

70   Constructor
71       POE::Wheel subclasses tend to perform a lot of setup so that they run
72       lighter and faster.  POE::Wheel::ReadWrite's constructor is no
73       exception.
74
75       new
76
77       new() creates and returns a new POE:Wheel::ReadWrite instance.  Under
78       most circumstances, the wheel will continue to read/write to one or
79       more filehandles until it's destroyed.
80
81       Handle
82
83       Handle defines the filehandle that a POE::Wheel::ReadWrite object will
84       read from and write to.  The "SYNOPSIS" includes an example using
85       Handle.
86
87       A single POE::Wheel::ReadWrite object can read from and write to
88       different filehandles.  See "InputHandle" for more information and an
89       example.
90
91       InputHandle
92
93       InputHandle and OutputHandle may be used to specify different handles
94       for input and output.  For example, input may be from STDIN and output
95       may go to STDOUT:
96
97         $_[HEAP]{console} = POE::Wheel::ReadWrite->new(
98           InputHandle => \*STDIN,
99           OutputHandle => \*STDOUT,
100           InputEvent => "console_input",
101         );
102
103       InputHandle and OutputHandle may not be used with Handle.
104
105       OutputHandle
106
107       InputHandle and OutputHandle may be used to specify different handles
108       for input and output.  Please see "InputHandle" for more information
109       and an example.
110
111       Driver
112
113       Driver specifies how POE::Wheel::ReadWrite will actually read from and
114       write to its filehandle or filehandles.  Driver must be an object that
115       inherits from POE::Driver.
116
117       POE::Driver::SysRW, which implements sysread() and syswrite(), is the
118       default.  It's used in nearly all cases, so there's no point in
119       specifying it.
120
121       TODO - Example.
122
123       Filter
124
125       Filter is the parser that POE::Wheel::ReadWrite will used to recognize
126       input data and the serializer it uses to prepare data for writing.  It
127       defaults to a new POE::Filter::Line instance since many network
128       protocols are line based.
129
130       TODO - Example.
131
132       InputFilter
133
134       InputFilter and OutputFilter may be used to specify different filters
135       for input and output.
136
137       TODO - Example.
138
139       OutputFilter
140
141       InputFilter and OutputFilter may be used to specify different filters
142       for input and output. Please see "InputFilter" for more information and
143       an example.
144
145       InputEvent
146
147       InputEvent specifies the name of the event that will be sent for every
148       complete input unit (as parsed by InputFilter or Filter).
149
150       Every input event includes two parameters:
151
152       "ARG0" contains the parsed input unit, and "ARG1" contains the unique
153       ID for the POE::Wheel::ReadWrite object that generated the event.
154
155       InputEvent is optional.  If omitted, the POE::Wheel::ReadWrite object
156       will not watch its Handle or InputHandle for input, and no input events
157       will be generated.
158
159       A sample InputEvent handler:
160
161         sub handle_input {
162           my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
163           print "Echoing input from wheel $wheel_id: $input\n";
164           $heap->{wheel}->put($input); # Put... the input... beck!
165         }
166
167       FlushedEvent
168
169       FlushedEvent specifies the event that a POE::Wheel::ReadWrite object
170       will emit whenever its output buffer transitions from containing data
171       to becoming empty.
172
173       FlushedEvent comes with a single parameter: "ARG0" contains the unique
174       ID for the POE::Wheel::ReadWrite object that generated the event.  This
175       may be used to match the event to a particular wheel.
176
177       "Flushed" events are often used to shut down I/O after a "goodbye"
178       message has been sent.  For example, the following input_handler()
179       responds to "quit" by instructing the wheel to say "Goodbye." and then
180       to send a "shutdown" event when that has been flushed to the socket.
181
182         sub handle_input {
183           my ($input, $wheel_id) = @_[ARG0, ARG1];
184           my $wheel = $_[HEAP]{wheel}{$wheel_id};
185
186           if ($input eq "quit") {
187             $wheel->event( FlushedEvent => "shutdown" );
188             $wheel->put("Goodbye.");
189           }
190           else {
191             $wheel->put("Echo: $input");
192           }
193         }
194
195       Here's the shutdown handler.  It just destroys the wheel to end the
196       connection:
197
198         sub handle_flushed {
199           my $wheel_id = $_[ARG0];
200           delete $_[HEAP]{wheel}{$wheel_id};
201         }
202
203       ErrorEvent
204
205       ErrorEvent names the event that a POE::Wheel::ReadWrite object will
206       emit whenever an error occurs.  Every ErrorEvent includes four
207       parameters:
208
209       "ARG0" describes what failed, either "read" or "write".  It doesn't
210       name a particular function since POE::Wheel::ReadWrite delegates actual
211       reading and writing to a POE::Driver object.
212
213       "ARG1" and "ARG2" hold numeric and string values for $! at the time of
214       failure.  Applicatin code cannot test $! directly since its value may
215       have changed between the time of the error and the time the error event
216       is dispatched.
217
218       "ARG3" contains the wheel's unique ID.  The wheel's ID is used to
219       differentiate between many wheels managed by a single session.
220
221       ErrorEvent may also indicate EOF on a FileHandle by returning operation
222       "read" error 0.  For sockets, this means the remote end has closed the
223       connection.
224
225       A sample ErrorEvent handler:
226
227         sub error_state {
228           my ($operation, $errnum, $errstr, $id) = @_[ARG0..ARG3];
229           if ($operation eq "read" and $errnum == 0) {
230             print "EOF from wheel $id\n";
231           }
232           else {
233             warn "Wheel $id encountered $operation error $errnum: $errstr\n";
234           }
235           delete $_[HEAP]{wheels}{$id}; # shut down that wheel
236         }
237
238       HighEvent
239
240       HighEvent and LowEvent are used along with HighMark and LowMark to
241       control the flow of streamed output.
242
243       A HighEvent is sent when the output buffer of a POE::Wheel::ReadWrite
244       object exceeds a certain size (the "high water" mark, or HighMark).
245       This advises an application to stop streaming output.  POE and Perl
246       really don't care if the application continues, but it's possible that
247       the process may run out of memory if a buffer grows without bounds.
248
249       A POE::Wheel::ReadWrite object will continue to flush its buffer even
250       after an application stops streaming data, until the buffer is empty.
251       Some streaming applications may require the buffer to always be primed
252       with data, however.  For example, a media server would encounter
253       stutters if it waited for a FlushedEvent before sending more data.
254
255       LowEvent solves the stutter problem.  A POE::Wheel::ReadWrite object
256       will send a LowEvent when its output buffer drains below a certain
257       level (the "low water" mark, or LowMark).  This notifies an application
258       that the buffer is small enough that it may resume streaming.
259
260       The stutter problem is solved because the output buffer never quite
261       reaches empty.
262
263       HighEvent and LowEvent are edge-triggered, not level-triggered.  This
264       means they are emitted once whenever a POE::Wheel::ReadWrite object's
265       output buffer crosses the HighMark or LowMark.  If an application
266       continues to put() data after the HighMark is reached, it will not
267       cause another HighEvent to be sent.
268
269       HighEvent is generally not needed.  The put() method will return the
270       high watermark state: true if the buffer is at or above the high
271       watermark, or false if the buffer has room for more data.  Here's a
272       quick way to prime a POE::Wheel::ReadWrite object's output buffer:
273
274         1 while not $_[HEAP]{readwrite}->put(get_next_data());
275
276       POE::Wheel::ReadWrite objects always start in a low-water state.
277
278       HighEvent and LowEvent are optional.  Omit them if flow control is not
279       needed.
280
281       LowEvent
282
283       HighEvent and LowEvent are used along with HighMark and LowMark to
284       control the flow of streamed output.  Please see "HighEvent" for more
285       information and examples.
286
287       TODO - Example here.
288
289   put RECORDS
290       put() accepts a list of RECORDS, which will be serialized by the
291       wheel's Filter and buffered and written by its Driver.
292
293       put() returns true if a HighMark has been set and the Driver's output
294       buffer has reached or exceeded the limit.  False is returned if
295       HighMark has not been set, or if the Driver's buffer is smaller than
296       that limit.
297
298       put()'s return value is purely advisory; an application may continue
299       buffering data beyond the HighMark---at the risk of exceeding the
300       process' memory limits.  Do not use "<1 while not $wheel-"put()>>
301       syntax if HighMark isn't set: the application will fail spectacularly!
302
303   event EVENT_TYPE => EVENT_NAME, ...
304       event() allows an application to modify the events emitted by a
305       POE::Wheel::ReadWrite object.  All constructor parameters ending in
306       "Event" may be changed at run time: "InputEvent", "FlushedEvent",
307       "ErrorEvent", "HighEvent", and "LowEvent".
308
309       Setting an event to undef will disable the code within the wheel that
310       generates the event.  So for example, stopping InputEvent will also
311       stop reading from the filehandle.  "pause_input" and "resume_input" may
312       be a better way to manage input events, however.
313
314       TODO - Example.
315
316   set_filter POE_FILTER
317       set_filter() changes the way a POE::Wheel::ReadWrite object parses
318       input and serializes output.  Any pending data that has not been
319       dispatched to the application will be parsed with the new POE_FILTER.
320       Information that has been put() but not flushed will not be
321       reserialized.
322
323       set_filter() performs the same act as calling set_input_filter() and
324       set_output_filter() with the same POE::Filter object.
325
326       Switching filters can be tricky.  Please see the discussion of
327       get_pending() in POE::Filter.  Some filters may not support being
328       dynamically loaded or unloaded.
329
330       TODO - Example.
331
332   set_input_filter POE_FILTER
333       set_input_filter() changes a POE::Wheel::ReadWrite object's input
334       filter while leaving the output filter unchanged.  This alters the way
335       data is parsed without affecting how it's serialized for output.
336
337       TODO - Example.
338
339   set_output_filter POE_FILTER
340       set_output_filter() changes how a POE::Wheel::ReadWrite object
341       serializes its output but does not affect the way data is parsed.
342
343       TODO - Example.
344
345   get_input_filter
346       get_input_filter() returns the POE::Filter object currently used by a
347       POE::Wheel::ReadWrite object to parse incoming data.  The returned
348       object may be introspected or altered via its own methods.
349
350       There is no get_filter() method because there is no sane return value
351       when input and output filters differ.
352
353       TODO - Example.
354
355   get_output_filter
356       get_output_filter() returns the POE::Filter object currently used by a
357       POE::Wheel::ReadWrite object to serialize outgoing data.  The returned
358       object may be introspected or altered via its own methods.
359
360       There is no get_filter() method because there is no sane return value
361       when input and output filters differ.
362
363       TODO - Example.
364
365   set_high_mark HIGH_MARK_OCTETS
366       Sets the high water mark---the number of octets that designates a "full
367       enough" output buffer.  A POE::Wheel::ReadWrite object will emit a
368       HighEvent when its output buffer expands to reach this point.  All
369       put() calls will return true when the output buffer is equal or greater
370       than HIGH_MARK_OCTETS.
371
372       Both HighEvent and put() indicate that it's unsafe to continue writing
373       when the output buffer expands to at least HIGH_MARK_OCTETS.
374
375       TODO - Example.
376
377   set_low_mark LOW_MARK_OCTETS
378       Sets the low water mark---the number of octets that designates an
379       "empty enough" output buffer.  This event lets an application know that
380       it's safe to resume writing again.
381
382       POE::Wheel::ReadWrite objects will emit a LowEvent when their output
383       buffers shrink to LOW_MARK_OCTETS after having reached
384       HIGH_MARK_OCTETS.
385
386       TODO - Example.
387
388   ID
389       ID() returns a POE::Wheel::ReadWrite object's unique ID.  ID() is
390       usually called after the object is created so that the object may be
391       stashed by its ID.  Events generated by the POE::Wheel::ReadWrite
392       object will include the ID of the object, so that they may be matched
393       back to their sources.
394
395       TODO - Example.
396
397   pause_input
398       pause_input() instructs a POE::Wheel::ReadWrite object to stop watching
399       for input, and thus stop emitting InputEvent events.  It's much more
400       efficient than destroying the object outright, especially if an
401       application intends to resume_input() later.
402
403       TODO - Example.
404
405   resume_input
406       resume_input() turns a POE::Wheel::ReadWrite object's input watcher
407       back on.  It's used to resume watching for input, and thus resume
408       sending InputEvent events.  pause_input() and resume_input() implement
409       a form of input flow control, driven by the application itself.
410
411       TODO - Example.
412
413   get_input_handle
414       get_input_handle() returns the filehandle being watched for input.
415
416       Manipulating filehandles that are managed by POE may cause nasty side
417       effects, which may change from one POE release to the next.  Please use
418       caution.
419
420       TODO - Example.
421
422   get_output_handle
423       get_output_handle() returns the filehandle being watched for output.
424
425       Manipulating filehandles that are managed by POE may cause nasty side
426       effects, which may change from one POE release to the next.  Please use
427       caution.
428
429       TODO - Example.
430
431   shutdown_input
432       Call shutdown($fh,0) on a POE::Wheel::ReadWrite object's input
433       filehandle.  This only works for sockets; nothing will happen for other
434       types of filehandle.
435
436       Occasionally, the POE::Wheel::ReadWrite object will stop monitoring its
437       input filehandle for new data.  This occurs regardless of the
438       filehandle type.
439
440       TODO - Example.
441
442   shutdown_output
443       Call shutdown($fh,1) on a POE::Wheel::ReadWrite object's output
444       filehandle.  This only works for sockets; nothing will happen for other
445       types of filehandle.
446
447       Occasionally, the POE::Wheel::ReadWrite object will stop monitoring its
448       output filehandle for new data. This occurs regardless of the
449       filehandle type.
450
451       TODO - Example.
452
453   get_driver_out_octets
454       POE::Driver objects contain output buffers that are flushed
455       asynchronously.  get_driver_out_octets() returns the number of octets
456       remaining in the wheel's driver's output buffer.
457
458       TODO - Example.
459
460   get_driver_out_messages
461       POE::Driver objects' output buffers may be message based.  Every put()
462       call may be buffered individually.  get_driver_out_messages() will
463       return the number of pending put() messages that remain to be sent.
464
465       Stream-based drivers will simply return 1 if any data remains to be
466       flushed.  This is because they operate with one potentially large
467       message.
468
469       TODO - Example.
470
471   flush
472       flush() manually attempts to flush a wheel's output in a synchronous
473       fashion.  This can be used to flush small messages.  Note, however,
474       that complete flushing is not guaranteed---to do so would mean
475       potentially blocking indefinitely, which is undesirable in most POE
476       applications.
477
478       If an application must guarantee a full buffer flush, it may loop
479       flush() calls:
480
481         $wheel->flush() while $wheel->get_driver_out_octets();
482
483       However it would be prudent to check for errors as well.  A flush()
484       failure may be permanent, and an infinite loop is probably not what
485       most developers have in mind here.
486
487       It should be obvious by now that this method is experimental.  Its
488       behavior may change or it may disappear outright.  Please let us know
489       whether it's useful.
490
491       # TODO - Example?
492

SEE ALSO

494       POE::Wheel describes wheels in general.
495
496       The SEE ALSO section in POE contains a table of contents covering the
497       entire POE distribution.
498

BUGS

500       None known.
501

AUTHORS & COPYRIGHTS

503       Please see POE for more information about authors and contributors.
504
505
506
507perl v5.12.1                      2010-04-03          POE::Wheel::ReadWrite(3)
Impressum