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

SEE ALSO

450       POE::Wheel describes wheels in general.
451
452       The SEE ALSO section in POE contains a table of contents covering the
453       entire POE distribution.
454

BUGS

456       None known.
457

AUTHORS & COPYRIGHTS

459       Please see POE for more information about authors and contributors.
460
461
462
463perl v5.32.0                      2020-07-28          POE::Wheel::ReadWrite(3)
Impressum