1POE::Wheel::ReadWrite(3U)ser Contributed Perl DocumentatiPoOnE::Wheel::ReadWrite(3)
2
3
4
6 POE::Wheel::ReadWrite - non-blocking buffered I/O mix-in for
7 POE::Session
8
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
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
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
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
500 None known.
501
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)