
=head1 NAME 

POE - Perl Object Environment


=head1 DESCRIPTION

POE is a high-level, object oriented framework for writing event driven programs. Being designed to take care of most of the fiddly mucking about with select and sockets, it especially lends itself to multi-session servers and clients.

POE comes with seventeen complete, commented sample/test programs in the distribution's tests subdirectory. Please see the  [unknown tag L] Tests and Example Programs section near the end of this file for a brief explanation of each. F<tests/tutorial-chat.perl>, in particular, is a quick introduction to using POE.

POE's original purpose was to provide a runtime "agent space" in which objects ('bots) and users can roam and interact. However, because POE's events framework is useful by itself, it has been released without objects

=over 2

=item 1 Design Goals

The design goals are mostly fluff. You won't learn how to use POE by reading them.

=over 2

=item 1 Simplicity

POE is based on very simple ideas. Events, sessions to receive them, functions to manipulate resources. Each feature is designed for ease of use, mainly because the author intends to use them a lot.

Most of the subsequent design goals overlap with POE's simplicity.

=item 2 Layers

POE is separated into distinct layers. Each layer adds features over previous layers without depending on subsequent ones. This allows developers to use subsets of POE without including unnecessary code.

=item 3 Abstraction

POE hides most of the tedious, redundant details of event-driven programming behind high-level, functional interfaces. Some of the interfaces are abstracted even further in other POE layers. This lets developers pick the level of abstraction they're comfortable with.

=item 4 Flexibility

POE avoids assumptions and artificial limitations wherever possible. Previous versions didn't, and it caused the author a lot of grief.

=item 5 Invisibility

POE provides its services cleanly and quietly. POE objects are designed to plug themselves into the events layer when they are created. They quietly perform their jobs while they exist, and they cleanly unplug themselves when they are destroyed. POE tracks its own references and collects its own garbage.

=item 6 Portability

Please see the README for the latest portability information.


=back


=back

=head1 Quick Start / Tutorial

This section's not written yet. The F<tests/tutorial-chat.perl> program is a very simple, working example. It contains lots of narrative and comments. The other example programs show how to use POE for other things.


=head1 Events Layer

POE's events layer is implemented in two classes: C<POE::Kernel> and C<POE::Session>. C<Kernel> contains the event queue and resource manager. C<Session> instances are bundles of event handlers, similar to operating system processes or threads.

Sessions may also be thought of as state machines. When considering POE from this point of view, event handlers become states in the machine, and events signal transitions from one state to another. The event-driven nature of POE's state machines allows them to cooperatively multi-thread within themselves and multitask with each-other.

Consider this simple Perl code, for example:

  my $i = 0;
  while ($i < 100) {
    print $i++, "\n";
  }
  exit;

It can be represented as a finite automata (state machine) consisting of four states:

  1. Set $i to 0, and go to state 2.
  2. Test $i < 100.  If true, go to state 3; otherwise go to state 4.
  3. Display $i, increment it, and go to state 2.
  4. Exit.

These simplified event handlers represent the previous state machine:

  _start  => sub { post(1); },
  1       => sub { $i = 1; post(2); },
  2       => sub { if ($i < 100) { post(3); } else { post(4); } },
  3       => sub { print $i++, "\n"; post(2); },
  4       => sub { }, # do nothing, and the session stops

To be sure, this is a lot slower than the original procedural code, but it has the benefit of cooperating with itself and other sessions within the same program.

=over 2

=item 1 Sessions

B<Session constructors have changed in version 0.06.> Processes no longer support multiple kernels. This obsoleted the C<$kernel> parameter for session constructors, and it was removed.

Sessions are POE's basic, self-contained units of execution. They are equivalent to processes or threads in real operating systems. Sessions register themselves with POE's kernel when they are created. The kernel manages their resources until they stop.

=over 2

=item 1 Session Methods

These are C<POE::Session>'s public methods.

=over 2

=item 1 C<POE::Session::debug(...)>

C<POE::Session::option()> toggles the session's options flags. B<This replaces C<$_[HEAP]-E<62>{'_debug'}> in version 0.06.> Currently, options are mostly for debugging:

=over 2

=item * trace - Boolean. Trace events as they arrive at the session.

=item * default - Boolean. Note events that can't be handled.

=back

  $_[SESSION]->option( trace => 1, default => 0 );

Boolean values may be either C<1>, C<0>, C<'on'>, C<'off'>, C<'yes'> or C<'no'>.

C<POE::Session::option()> only changes the options that are present as parameters. All other options are left alone.


=back

=item 2 Session Types

There currently are four kinds of sessions: Inline, Object, Package and Hybrid. Each type provides a way to build sessions from different kinds of event handlers, and each has a different constructor syntax.

=over 2

=item 1 Inline Sessions

Inline sessions consist of event names, each followed by a reference to the code that handles the event.

  new POE::Session(
        name1 => \&name1_handler, # handles the "name1" event
        name2 => sub { ... },     # handles the "name2" event
        \@start_args,             # ARG0..ARGn for the _start event
  );

Events delivered to inline sessions have C<undef> in their C<OBJECT> parameters.

=item 2 Object Sessions

Object sessions consist of blessed object references, each followed by a reference to an array of events that the object will handle. Each object must have methods named after the events it handles.

Remember that C<=E<62>> stringifies its left value. Using it for object sessions will cause object references to lose their blessing.

  my $object1 = new SomeObject(...);
  my $object2 = new SomeOtherObject(...);
  new POE::Session(
        $object1, [ 'name1', 'name2' ],
        $object2, [ 'name3', 'name4' ],
        \@start_args,
  );

Events delivered to object sessions have a reference to the object in their C<OBJECT> parameters. sessions.

=item 3 Package Sessions

Package sessions are similar to object sessions, but they use package names instead of object references. The C<=E<62>> operator works for this one. Event handlers are called as package

  new POE::Session(
        $package, [ 'name1', # $package->'name1' handles "name1"
                    'name2'  # $package->'name2' handles "name2"
                  ],
        \@start_args,
  );

Events delivered to package sessions have the package name in their C<OBJECT> parameters.

=item 4 Hybrid Sessions

Hybrid objects contain a mix of available event handlers.

  my $object1 = new SomeObject(...);
  my $object2 = new SomeOtherObject(...);
  new POE::Session(
        \@start_args,
        $object1, [ 'name11', 'name12' ],
        'name01' => sub { ... },
        'name02' => sub { ... },
        $object2, [ 'name21', 'name22' ],
        'name03' => sub { ... },
        'name04' => sub { ... },
        $package3, [ 'name31', 'name32' ],
  );

Events delivered to hybrid sessions have various values for C<OBJECT>. The particular value depends on how the event handler was registered.


=back


=back

=item 2 About Event Handlers

Event handlers are evaluated in a scalar context. Handlers may use array references if they need to return multiple values. Return values are used by signal handlers, to tell the kernel whether or not the signal was handled. They also are returned to the caller if an event handle is called directly. See B<_signal> or C<POE::Kernel::call> for more on that.

If an event handler returns a reference to a POE object, it will be stringified. This is done to prevent "blessing bleed" (see the Changes file) from interfering with POE's garbage collection. The code that checks for POE objects does not look inside data passed by reference-- it's just there to catch accidents, like this example:

  sub stop_handler {
    delete $_[HEAP]->{'readwrite wheel'};
    # reference to the readwrite wheel is implicitly returned
  }

That accidentally returns a reference to a POE::Wheel::ReadWrite object. If the reference was not stringified, it would delay the wheel's destruction until after the session stopped. The wheel would try to remove its states from the nonexistent session, and a runtime error would occur.

=item 3 Kernel

The C<POE::Kernel> class contains POE's event loop and functions to manage events and other resources.

=over 2

=item 1 Kernel Management

B<Kernel management has changed in version 0.06.> Support for multiple kernels has been removed, enabling better signal support in 0.06 and simplifying threads support in the future. As a result, explicitly creating kernels has been deemed silly and is now handled by C<POE::Kernel> the first time it's used. The C<new()> method still exists, and nothing will break if it's called, but it's just not necessary now.

The program's single kernel is automatically initialized the first time C<POE::Kernel> is used. C<POE::Kernel> exports C<$poe_kernel>, a reference to the global kernel, each time it's used.

=over 2

=item 1 C<POE::Kernel::run>

This starts the kernel's event loop. It will not return until all the sessions it manages end. There are two corollaries: If there are no sessions, it will end immediately; and if sessions never exit, neither will C<run()>.

  # includes POE::Kernel and POE::Session by default
  use POE;

  # set up initial sessions here

  $poe_kernel->run();
  exit;


=back

=item 2 Events

Events inform sessions when it is time to do something. In turn, sessions invoke their corresponding handlers. For example, when a session receives a B<_start> event, it invokes its event handler named C<'_start'>.

There are two ways to send events to sessions. Events can be posted, in which case the kernel queues them and dispatches them in FIFO order. Event handlers can also be called immediately, bypassing the queue. Immediate calls can be useful for critical code or events that should not be delayed. POE's wheels use C<call> to minimize event latency.

=over 2

=item 1 Event Management Functions

These functions manage events. No, really!

=over 2

=item 1 C<Kernel::post>

C<Kernel::post> places an event in the kernel's queue. The kernel dispatches queued events in FIFO order. Event handlers are evaluated in a scalar context, and their return values are discarded.

  $kernel->post($destination_session, $event_name, @args);

Whatever the C<$event_name> handler returns is lost. If a return value is important, there are two ways to get it. First, have the C<$destination_session> post a return event to C<$_[FROM]>; second, use C<Kernel::call>.

=item 2 C<Kernel::yield>

C<Kernel::yield> is an alias for posting an event to the current session. It does not operate like C<yield> in real thread libraries (swapping stacks in plain Perl is a hard thing to do).

C<Kernel::yield> does not need a C<$destination_session> parameter because the kernel already knows which session is running. Event handlers are evaluated in a scalar context, and their return values are discarded.

  $kernel->yield($event_name, @args);

=item 3 C<Kernel::call>

C<Kernel::call> immediately dispatches an event to its session. Event handlers are evaluated in a scalar context, and C<call> returns their return values.

  my $handler_return_value =
         $kernel->call( $destination_session,
                        $event_name, @args
                      );

C<Kernel::call> can exercise bugs in Perl and/or the C library (we're not sure which just yet). This only seems to occur while destroying an event handler from another event handler that is directly called by the first one. Until this is fixed, if your POE program dumps core with a SIGSEGV, change your C<Kernel::call> invocations to C<Kernel::post> and they should go away.


=back

=item 2 Event Handler Parameters

B<Event handler parameters have changed in version 0.06.> Prior to version 0.06, inline handlers received different parameters than object and package handlers. The call signatures have been unified in version 0.06. This breaks programs written with POE 0.05 or earlier.

To prevent future breakage, C<POE::Session> now exports constants for parameters' offsets into C<@_>. Programs that use them guaranteed not to break if existing parameters are rearranged or new ones are added. If parameters are removed in the future, programs will break at compile time instead of silently failing during runtime.

Parameters may be used discretely as C<$_[KERNEL]>. If several parameters are needed multiple times, it may be faster to assign them to lexicals all at once with an array slice:

  my ($kernel, $operation, $errnum, $errstr) =
     @_[KERNEL, ARG0, ARG1, ARG2];

The parameter constants are:

=over 2

=item 1 C<OBJECT>

C<$_[OBJECT]>'s value depends on the type of event handler. For inline handlers, it is C<undef>. For object handlers, it contains a reference to the object that owns the handler. For package handlers, it contains the name of the package.

=item 2 C<KERNEL>

C<$_[KERNEL]> is a reference to the kernel that is managing this session. It is provided in case the event handler was defined in a scope where C<$poe_kernel> is unavailable.

=item 3 C<SESSION>

C<$_[SESSION]> is a reference to the current session object. Direct manipulation of its contents and methods is not supported. It is included for use as a parameter to C<Kernel> methods.

=item 4 C<HEAP>

C<$_[HEAP]> is a reference to a hash set aside for sessions to store global data. Information stored in the heap will be available to all the event handlers in the session, and it will persist until the session stops.

POE will delete the heap from its internal structures, but developers are expected to remove anything from it that would leak memory.

B<Support for using the C<HEAP> (formerly known as C<$me> or C<$namespace>) as an alias for C<SESSION> in Kernel method calls is depreciated in version 0.06, and it will be removed in version 0.07.>

=item 5 C<FROM>

C<$_[FROM]> is a reference to the session that sent the event. It is suitable as a destination for responses. If using C<call> in both directions, be aware that POE does not prevent deep recursion.

=item 6 C<ARG0..ARG9>

C<@_[ARG0 .. ARG9]> are the first ten elements of C<@args> as passed to C<post>, C<call>, C<yield> or C<alarm>. If more than ten items are needed, they may be referenced as C<$_[ARG9+1..]>, but it would be more efficient to pass them all as an array reference in C<ARG0>.


=back

=item 3 Predefined Events E<38> Parameters

POE reserves some event names for internal and standard use. All its predefined events begin with an underscore, and future ones will too. It may be wise to avoid leading underscores in your own event names.

Every predefined event is accompanied by C<OBJECT>, C<KERNEL>, C<SESSION>, C<HEAP> and C<FROM>.

=over 2

=item 1 B<_start>

Sessions register themselves with the kernel when they are created. Kernels dispatch B<_start> events to sessions when the registration is complete. Sessions may then begin interacting with the kernel in a sane way.

POE requires every session to have a C<_start> handler, otherwise how would they know when it's okay to start?

C<FROM> contains a reference to the session that started this session.

C<ARG0..ARG9> contain arguments as they were given to the session constructor.

=item 2 B<_stop>

Kernels keep track of the resources that sessions use. Some resources guarantee that the session will receive events. These include enqueued events, selects (filehandle monitors), child sessions, and aliases. Sessions that run out of these resources become starved for events, and kernels removes them. Before it removes them, it issues a C<_stop> event. This gives sessions an opportunity to clean up.

C<FROM> is the session that posted the B<_stop> event. In the case of resource starvation, this is the C<KERNEL>. If B<_stop> was posted, it contains a reference to the session that posted it.

C<ARG0..ARG9> are empty in the case of resource starvation. If the B<_stop> event was posted, they may contain other values.

=item 3 B<_signal>

B<Signal handling has changed slightly in version 0.06.>

POE sets handlers for most of the signals in C<%SIG>. The only exceptions are things which might exist in C<%SIG> but probably shouldn't. POE will not register a signal handler for C<RTMIN>, for example, because doing so breaks Perl for HP-UX.

Signals are propagated to children of the destination session first. Since every session ultimately is a descendent of the kernel, posting signals to the kernel guarantees that every session receives them.

POE does not magically solve Perl's problems with signals. Yet.

Currently there are three types of signals. The kernel processes each in a different way:

C<SIGPIPE> causes a B<_signal> event to be posted directly to the session that is running when the signal was received. C<ARG0> contains the signal name as it appears in C<%SIG>.

C<SIGCHLD> and/or C<SIGCLD> call C<wait> to acquire the dying child's process ID. A B<_signal> event will be posted to all sessions if the child PID is valid. C<ARG0> contains C<CHLD> regardless of the actual signal name, C<ARG1> contains the child PID, and C<ARG2> contains the contents of C<$?> just after the C<wait> call.

All other signals cause a B<_signal> event to be posted to all sessions. C<ARG0> contains the signal name as it appears in C<%SIG>.

=item 4 B<_garbage_collect>

The B<_garbage_collect> event tells the kernel to check a session's resources and stop it if none are left. It never is dispatched to a session. This was added to delay garbage collection for new sessions, allowing parent sessions to interact with them before they stop.

=item 5 B<_parent>

The B<_parent> event lets child sessions know that they are about to be orphaned, and it tells them their new parents. It is dispatched to child sessions before parents receive their B<_stop> events.

C<FROM> should always equal C<KERNEL>. If it does not, then the event was sent by a session other than the kernel. C<ARG0> is this session's old parent; C<ARG1> is the new parent.

=item 6 B<_child>

The B<_child> event is sent to parent sessions when they acquire or lose child sessions. B<_child> is dispatched to parents after the children receive B<_start> or before they receive B<_stop>.

C<FROM> should always equal C<KERNEL>. If it does not, then the event was sent by a session other than the kernel.

C<ARG0> indicates what is happening to the child. It is C<'gain'> if the session is a grandchild being given by a dying child. It is C<'lose'> if the session is itself a dying child. It is C<'create'> if the child was created by the current session.

C<ARG1> is a reference to the child session. It will still be valid, even if the child is in its death throes.

C<ARG2> is only valid when C<ARG0> contains C<'create'>. It contains the return value of the child's B<_start> event handler, which was evaluated in a scalar context (and stringified if it was a reference to a POE::* object).

=item 7 B<_default>

The B<_default> handler is invoked whenever a session receives an event it can't handle. The event is discarded if the session doesn't have a B<_default> handler. This prevents POE from recursing until perl's stack eats the machine.

C<ARG0> contains the name of the original event. C<ARG1> contains a reference to the original event's C<ARG0..> parameters.

B<_default> can be useful for detecting misspelled event names or handling strange signals. So can C<POE::Session::debug()>.


=back


=back

=item 3 Alarms

Alarms are just events that are scheduled to be dispatched at some point in the future. POE will use C<Time::HiRes>, if it's available, to allow fractional alarm times.

=over 2

=item 1 C<Kernel::alarm>

C<Kernel::alarm> enqueues an event with a future dispatch time, specified in seconds since the unix epoch.

  $kernel->alarm($event_name, $dispatch_time, @args);

If C<$dispatch_time> is in the past, it will be clipped to C<time>.

Alarms are keyed on their event names. It is possible to remove an alarm that hasn't yet been dispatched by omitting the other parameters:

  $kernel->alarm($event_name);  # clears the $event_name alarm

Subsequent alarms set for the same name will overwrite previous ones. This is useful for setting timeout timers.

C<Kernel::alarm> can be misused to remove events from the kernel's queue. This happens because alarms are merely events scheduled to be dispatched in the future. B<This behavior is not supported and may change.> If someone finds it to be useful, please contact the author.

=item 2 C<Kernel::delay>

C<Kernel::delay> enqueues an event for a certain amount of time in the future. It is a shortcut for calling C<Kernel::alarm> with C<time + $delay>. It automagically uses a high-resolution version of C<time>, if C<Time::HiRes> is available.

To set a delay:

  $kernel->delay($event_name, $delay, @args);

As with C<Kernel::alarm>, omitting the other parameters will remove a delay:

  $kernel->delay($event_name);  # clears the $event_name delay

C<Kernel::delay> can be misused to remove events from the kernel's queue. This happens because alarms are merely events scheduled to be dispatched in the future. B<This behavior is not supported and may change.> If someone finds it to be useful, please contact the author.


=back

=item 4 Aliases

Aliases allow sessions to be referred to by name. They also allow sessions to remain active without having open selects or events. This provides support for "daemon" sessions that act as resources but don't do much by themselves.

Aliases must be unique. Sessions may have more than one alias.

=over 2

=item 1 C<Kernel::alias_set>

Sets an alias for the current session.

  $kernel->alias_set($alias);

Returns 1 on success. On failure, it returns 0 and sets C<$!> to one of:

=over 2

=item * C<EEXIST> - the alias exists for another session

=back

=item 2 C<Kernel::alias_remove>

Removes an alias for the current session.

  $kernel->alias_remove($alias);

Returns 1 on success. On failure, it returns 0 and sets C<$!> to one of:

=over 2

=item * C<ESRCH> - the alias does not exist

=item * C<EPERM> - the alias belongs to another session

=back

=item 3 C<Kernel::alias_resolve>

Resolves an alias to a session reference. Kernels do this internally, so it usually is not necessary.

  my $session_reference = $kernel->alias_resolve($alias_name);

Returns a session reference on success. On failure, it returns undef and sets C<$!> to one of:

=over 2

=item * C<ESRCH> - the alias does not exist

=back


=back

=item 5 Selects

Selects are filehandle monitors. They cause kernels to generate events when file activity occurs. Files are automatically closed when all the selects watching them are released.

There are three types of select, each corresponding to one of the bit vectors in Perl's four-argument select() function. Read selects generate events when files become ready for reading. Write selects generate events when files are available to be written to. Expedite selects generate events when out-of-band information becomes available for reading.

=over 2

=item 1 C<Kernel::select>

C<Kernel::select> allows sessions to add, change or remove all three selects for a filehandle at once. Undefined event names remove their corresponding selects.

  $kernel->select( $filehandle,
                   $read_event_name,    # or undef to remove
                   $write_event_name,   # or undef to remove
                   $expedite_event_name # or undef to remove
  );

=item 2 C<Kernel::select_read>

This function adds, changes or removes a filehandle's read select. The other selects remain unchanged.

  $kernel->select_read($filehandle, $read_event_name);

=item 3 C<Kernel::select_write>

This function adds, changes or removes a filehandle's write select. The other selects remain unchanged.

  $kernel->select_write($filehandle, $write_event_name);

=item 4 C<Kernel::select_expedite>

This function adds, changes or removes a filehandle's expedite select. The other selects remain unchanged.

  $kernel->select_expedite($filehandle, $expedite_event_name);


=back

=item 6 Signals

The kernel generates B<_signal> events when it receives signals from the underlying operating system. Sessions may also send signals between themselves without involving the OS.

The kernel determines whether or not signals have been handled by looking at B<_signal> handlers' return values. Boolean true indicates that a signal was handled; boolean false means it wasn't.

Some signals will cause a kernel to stop a session if they aren't handled. These "terminal" signals are C<QUIT>, C<INT>, C<KILL>, C<TERM> and C<HUP>.

  sub hup_handler {
    my $heap = $_[HEAP];
    &close_files($heap);   # close log files
    &rotate_files($heap);  # rotate logs
    &open_files($heap);    # open new log files
    1;                     # and don't _stop the session!
  }

Finally, there is one fictitious signal that always stops a session: C<ZOMBIE>. When the kernel runs out of events, alarms and selects, it sends any remaining sessions a C<ZOMBIE> signal. This lets them know that the event queue has stalled, and they're as good as dead anyway.

=over 2

=item 1 C<Kernel::sig>

Signals normally post B<_signal> events to sessions. C<Kernel::sig> allows sessions to receive different events for each signal.

To receive B<sigint_event> instead of B<_signal> for C<SIGINT>:

  $kernel->sig('INT', 'sigint_event');

To receive B<_signal> for C<SIGINT> once again:

  $kernel->sig('INT');

=item 2 C<Kernel::signal>

C<Kernel::signal> simulates a signal. It bypasses the operating system, so the signal's name is not limited to what the OS allows. Likewise, C<Kernel::sig> may be used to catch these fictitious signals.

  $kernel->sig('BOGUS', 'sigbogus_event');
  $kernel->signal($session, 'BOGUS');
  $kernel->signal($kernel, 'HUP'); # sends to every session


=back

=item 7 States

States are another name for event handlers. This was discussed in the Events Layer section. The name "state" is used here instead of "event_handler" because it's easier to type.

The kernel's state management function allows sessions to add, change and remove event handlers at runtime. Wheel constructors and destructors use this to add and remove event handlers from sessions.

=over 2

=item 1 C<Kernel::state>

C<Kernel::state> adds, changes or removes a session's state. This may be used to alter inline, object and package event handlers:

  $kernel->state($event_name, $code_reference);      # inline
  $kernel->state($object_reference, \@method_names); # object
  $kernel->state($package_name, \@function_names);   # package

Returns 1 on success. On failure, it returns 0 and sets C<$!> to one of:

=over 2

=item * C<ESRCH> - somehow, the current session does not exist

=back


=back


=back


=back

=head1 I/O Layer

The I/O layer abstracts low- and medium-level I/O into three functional classes: Drivers, Filters and Wheels.

=over 2

=item 1 Drivers

Drivers provide a generic interface for low-level I/O. Wheels use this interface to communicate over different types of files without having to know the details for each.

In theory, drivers should be interchangeable. In practice, there seems to be an impermeable barrier between the different C<SOCK_*> types. More on this in later versions, after C<Wheel::SocketFactory> acquires UDP support.

=over 2

=item 1 Generic Driver Interface

Drivers are expected to have at least four methods. The methods may be empty stubs if the underlying I/O doesn't require their functions.

=over 2

=item 1 C<Driver::new>

C<Driver::new> creates and initializes a new driver.

  my $driver = new POE::Driver::Something();

=item 2 C<Driver::get>

C<Driver::get> immediately tries to read information from a filehandle. It returns a reference to an array of received data chunks. The array may be empty if nothing could be read. The array reference it returns is suitable as a parameter to C<Filter::get>.

  my $chunks_for_filter = $driver->get($handle);

Wheels usually call C<Driver::get> from their read select handlers.

=item 3 C<Driver::put>

C<Driver::put> places raw data into the driver's output queue. Some drivers may flush data during C<put>. It accepts a reference to an array of writable chunks and returns the number of elements in the output queue. Wheels use the return value to know when to manage write selects and send events.

  my $enqueued = $driver->put($streamable_from_filter);

Wheels usually call C<Driver::put> from their own C<put> methods.

=item 4 C<Driver::flush>

C<Driver::flush> attempts to flush data from the driver's output queue to the file. It returns the number of elements remaining in the output queue after the flush.

  my $enqueued = $driver->flush($handle);

Wheels usually call C<Driver::flush> from their write select handlers.


=back

=item 2 Specific Drivers

These drivers implement specific types of I/O. They all follow the generic driver interface.

=over 2

=item 1 C<Driver::SendRecv>

B<This driver is not currently available. It is scheduled to be part of a future release, along with UDP support in C<Wheel::SocketFactory>.>

C<Driver::SendRecv> driver will be a generic interface to C<send> and C<recv>.

=item 2 C<Driver::SysRW>

C<Driver::SysRW> is a generic interface to C<sysread> and C<syswrite>.


=back


=back

=item 2 Filters

Filters provide a generic interface for low- and medium-level protocols. Wheels use this interface to communicate in different ways without having to know the details for each.

In theory, filters should be interchangeable. In practice, stream and block protocols tend to be incompatible. More on this in later versions, after C<Wheel::SocketFactory> acquires UDP support and things can be tried.

=over 2

=item 1 Generic Filter Interface

Filters are expected to have at least three methods. The methods implement fairly basic functions, and they all are expected to do something.

=over 2

=item 1 C<Filter::new>

C<Filter::new> creates and initializes a new filter.

  my $filter = new POE::Filter::Something();

=item 2 C<Filter::get>

C<Filter::get> translates raw stream data into logical units. It accepts a reference to an array of raw stream chunks (returned from C<Driver::get>) and returns a reference to an array of complete logical units. Some filters will hold onto partial logical units until they are completed in a subsequent C<Filter::get> call.

  my $logical_blocks = $filter->get($chunks_from_driver);

C<Filter::get> returns a reference to an empty array if the stream doesn't include enough information for a complete logical unit.

=item 3 C<Filter::put>

C<Filter::put> accepts a reference to an array of logical data units. It translates the data units into streamable representations (suitable for C<Driver::put>), and it returns them in a different array reference.

  my $streamable_for_driver = $filter->put($logical_blocks);


=back

=item 2 Specific Filters

These filters implement specific low- and medium-level protocols. They all follow the generic filter interface.

=over 2

=item 1 C<Filter::Line>

C<Filter::Line> translates streams to and from delimited lines.

To do: This filter is broken as designed. A future version will allow the end-of-line marker to be specified as a parameter to C<Filter::Line::new>. It may also have a method that allows the marker to be changed after the filter is created.

Regardless of the changes, it will maintain compatibility by default.

=over 2

=item 1 C<Line::get>

This function splits streams on newlines, using the regexp C</(\x0D\x0A?|\x0A\x0D?)/>. It returns as many complete lines as it finds. Incomplete lines are kept until they are completed.

=item 2 C<Line::put>

This function appends network newlines (C<"\x0D\x0A">) to its parameters in preparation for them to be written by a driver.


=back

=item 2 C<Filter::Reference>

C<Filter::Reference> translates streams to and from Perl references. It requires either C<Storable> or C<FreezeThaw>.

=over 2

=item 1 C<Reference::get>

C<Reference::get> reconstitutes streamed, frozen data into references. References will be blessed, if necessary. If the reference points to an object, be sure to C<use> its module before calling its methods.

  my $references = $ref_filter->get($frozen_data);

=item 2 C<Reference::put>

C<Reference::put> accepts one or more references. It freezes the references and returns them as streamable values.

  my $frozen_data = $ref_filter->put($reference);


=back

=item 3 Stream Filter

C<Filter::Stream> passes data through unchanged.

=over 2

=item 1 C<Stream::get>

C<Stream::get> returns an exact copy of its parameters.

=item 2 C<Stream::put>

C<Stream::put> returns an exact copy of its parameters.


=back


=back


=back

=item 3 Wheels

Wheels provide standard, reusable logic for filters and drivers. They are designed to manage the resources and objects they are given, to use Drivers and Filters more or less interchangeably, and to clean up the resources they use.

=over 2

=item 1 Generic Wheel Interface

The generic wheel interface is very simple. It consists of a constructor, a destructor and optional methods.

=over 2

=item 1 C<Wheel::new>

C<Wheel::new> creates and initializes a new wheel. Part of a wheel's initialization involves adding event handlers to its parent session and registering them with the kernel.

  $heap->{wheel} = new POE::Wheel::Something( ... );

Because wheels have wildly different functions, they tend also to have very different constructors.

=item 2 C<Wheel::DESTROY>

C<Wheel::DESTROY> removes the handlers from the parent session and releases the resources it manages. This all happens automatically when the parent session deletes its reference to the wheel.

  delete $heap->{wheel};

=item 3 C<Wheel::put>

Wheels hide the resources they use. For this reason, wheels that manage writable files must provide their own C<Wheel::put> methods. C<Wheel::put> combines C<Filter::put> and C<Driver::put> in predictable ways.


=back

=item 2 Specific Wheels

POE comes with a small assortment of wheels. This will grow as people need to do other things.

=over 2

=item 1 ListenAccept

C<Wheel::ListenAccept> waits for activity on a listening socket and accepts remote connections as they arrive. It generates events for successful and failed connections. C<EAGAIN> is not considered to be a failure. This wheel neither needs nor includes a C<put> method.

C<Wheel::ListenAccept> was intended to be used with other sources of sockets. It predates C<Wheel::SocketFactory> and is compatible with IO::Socket classes.

=over 2

=item 1 ListenAccept Methods

These are ListenAccept's methods.

=over 2

=item 1 C<ListenAccept::new>

C<ListenAccept::new> parameters include a listening socket handle and the names of events to be generated on successful and failed connections.

  my $wheel = new POE::Wheel::ListenAccept(
        Handle      => $socket_handle,     # listening socket
        AcceptState => $accept_event_name, # success event
        ErrorState  => $error_event_name   # failure event
  );


=back

=item 2 ListenAccept Events and Parameters

These are the events that C<Wheel::ListenAccept> emits, and the parameters each event includes.

=over 2

=item 1 B<AcceptState>

B<AcceptState> contains the name of the event that will be generated upon a successful connection.

C<ARG0> contains the accepted socket handle.

A sample AcceptState handler:

  sub accept_handler {
    my $handle = $_[ARG0];
    # optional security things with getpeername
    &create_server_session($handle);
  }

=item 2 B<ErrorState>

B<ErrorState> contains the name of the event that will be generated upon a failed connection.

C<ARG0> contains the name of the function that failed. This usually is C<'accept'>. C<ARG1> and C<ARG2> contain the numeric and string versions of C<$!> at the time of the failure, respectively.

A sample ErrorState handler:

  sub error_handler {
    my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
    warn "$operation error $errnum: $errstr";
  }


=back


=back

=item 2 ReadWrite

This wheel performs buffered I/O on a filehandle. It generates events for common file conditions, such as read availability. This wheel includes a C<put> method.

=over 2

=item 1 ReadWrite Methods

These are ReadWrite's methods.

=over 2

=item 1 C<ReadWrite::new>

C<ReadWrite::new> parameters include a file or socket handle, a driver and a filter, and the names of events to generate for different conditions.

  my $wheel = new POE::Wheel::ReadWrite(
        Handle       => $file_or_socket_handle,       # handle to R/W
        Driver       => new POE::Driver::Something(), # driver to use
        Filter       => new POE::Filter::Something(), # filter to use
        InputState   => $input_event_name,  # event to emit on input
        FlushedState => $flush_event_name,  # event to emit on flush
        ErrorState   => $error_event_name,  # event to emit on error
  );

This wheel currently does not support OOB data. Please contact the author if OOB support is needed.

=item 2 C<ReadWrite::put>

C<ReadWrite::put> enqueues output for the filehandle and enables the wheel's write select. It accepts one or more units of data, in its filter's format.


=back

=item 2 ReadWrite Events and Parameters

These are the events that C<Wheel::ReadWrite> emits, and the parameters each event includes.

=over 2

=item 1 B<InputState>

B<InputState> contains the name of the event that will be generated for each logical unit of input received. If the B<InputState> parameter is omitted, the wheel be write-only. This supports log file writing.

C<ARG0> contains a logical unit of input.

A sample InputState handler:

  sub input_handler {
    my ($heap, $input) = @_[HEAP, ARG0];
    print "Got input: $input\n";
    $heap->{wheel}->put($input);   # echo it back
  }

=item 2 B<FlushedState>

B<FlushedState> contains the name of the event that will be generated whenever the wheel's output queue becomes empty. This signals that all pending data has been written. It does not include parameters.

A sample FlushedState handler:

  sub flush_handler {
    delete $_[HEAP]->{wheel};  # disconnects after flush
  }

=item 3 B<ErrorState>

B<ErrorState> contains the name of the event that will be generated whenever the wheel encounters a file error.

C<ARG0> contains the name of the function that failed. This depends on the wheel's associated driver. C<ARG1> and C<ARG2> contain the numeric and string versions of C<$!> at the time of the failure, respectively.

A sample ErrorState handler:

  sub error_handler {
    my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
    warn "$operation error $errnum: $errstr";
  }


=back


=back

=item 3 FollowTail

This wheel generates events when data appears at the end of a file. It is a read-only wheel and does not include a C<put> method. It behaves a lot like a read-only version of C<Wheel::ReadWrite>.

=over 2

=item 1 FollowTail Methods

These are FollowTail's methods.

=over 2

=item 1 C<FollowTail::new>

C<FollowTail::new> parameters include a seekable filehandle to watch, a driver that can read from the file, a filter that can format the file's records, the name of an event handler that will process records, and the name of an event handler that will deal with errors. It now accepts an optional B<PollInterval> parameter. This determines how long to wait between checks for file activity.

  my $wheel = new POE::Wheel::FollowTail(
        Handle       => $file_handle,
        Driver       => new POE::Driver::Something(),
        Filter       => new POE::Filter::Something(),
        InputState   => $input_event_name,
        ErrorState   => $error_event_name,
        PollInterval => 1,
  );


=back

=item 2 FollowTail Events

These are the events that C<Wheel::FollowTail> emits, and the parameters each event includes.

=over 2

=item 1 B<InputState>

This event behaves exactly like B<InputState> for C<Wheel::ReadWrite>.

=item 2 B<ErrorState>

This event behaves exactly like B<ErrorState> for C<Wheel::ReadWrite>.


=back


=back

=item 4 SocketFactory

This wheel creates sockets, generating events when something happens to them. Success events come with connected sockets, ready to be used. Failure events are accompanied by error codes.

C<SocketFactory> currently supports the AF_UNIX domain, and TCP sockets within the AF_INET domain. AF_INET/UDP sockets are forthcoming.

=over 2

=item 1 SocketFactory Methods

Socket factories only have one method, C<new()>.

=over 2

=item 1 C<SocketFactory::new>

C<SocketFactory::new> does all the work. Its parameters are an amalgam of the parameters for C<socket()>, C<setsockopt()>, C<bind()>, C<listen()>, C<connect()>, and C<accept()>:

=over 2

=item 1 C<SocketDomain>

This is the C<DOMAIN> parameter for C<socket()>. Currently supported values are C<AF_UNIX> and C<AF_INET>. It is always required.

=item 2 C<SocketType>

This is the C<TYPE> parameter for C<socket()>. Currently supported values are C<SOCK_STREAM> and C<SOCK_DGRAM> (although datagram sockets are not tested at this time). It is always required.

=item 3 C<SocketProtocol>

This is the C<PROTOCOL> parameter for C<socket()>. Protocols may be specified by name or number (see F</etc/protocol>). The only supported protocol at this time is 'tcp'. C<SocketProtocol> is ignored for the C<AF_UNIX> domain, and it is required for C<AF_INET> sockets.

=item 4 C<BindAddress>

This is the address of the local interface that the socket will be bound to. It is required for all C<AF_UNIX> sockets and recommended for listening C<AF_INET>.

It defaults to C<INADDR_ANY> if it's not specified for C<AF_INET> sockets.

C<BindAddress> is expected to be a textual representation of the address. It will be packed, with or without an accompanying C<BindPort> as necessary for the socket domain.

=item 5 C<BindPort>

This is the port of the local interface that the socket will be bound to. It is ignored for all C<AF_UNIX> sockets and recommended for listening C<AF_INET> sockets. It defaults to C<0> if it's not specified for C<AF_INET> sockets.

C<BindPort> is expected to be a textual representation of the port. It may be specified by name or number.

=item 6 C<ListenQueue>

This parameter specifies the length of the socket's C<listen()> queue. For sockets that support connections, C<ListenQueue> helps determine whether to be a listening or connecting socket.

C<ListenQueue> is clipped to never exceed C<SOMAXCONN>.

=item 7 C<RemoteAddress>

This is the remote address to which the socket should connect. It is required for connecting sockets and ignored in all other cases.

C<RemoteAddress> is expected to be a textual representation of the address. It will be packed, with or without an accompanying C<RemotePort> as necessary for the socket domain.

=item 8 C<RemotePort>

This is the remote port to which the socket should connect. It is required for connecting C<AF_INET> sockets and ignored in all other cases.

C<RemotePort> is expected to be a textual representation of the port. It may be specified by name or number.

=item 9 C<SuccessState>

This is the name of the event that will be generated when the socket is successfully created. For sockets that support connections, this also indicates a connection was made.

C<SocketFactory> only generates one C<SuccessState> event when a connection has been established. For client sockets, this happens when the connection has gone through. For server sockets, this indicates that a client has successfully been accepted.

C<ARG0> always contains the connected or accepted socket.

If C<ARG0> is an accepted AF_INET socket, then C<ARG1> and C<ARG2> will contain the accepted socket's address and port, as returned by C<unpack_sockaddr_in>.

C<ARG1> and C<ARG2> are C<undef> for AF_UNIX sockets.

=item 10 C<FailureState>

This is the name of the event that will be generated when something goes wrong. C<EWOULDBLOCK> is not one of the conditions for generating this event.

As with other "error" events, C<ARG0> contains the syscall that failed, C<ARG1> contains the numeric version of C<$!> at the time of failure, and C<ARG2> contains the string version of C<$!>.


=back


=back

=item 2 SocketFactory Examples

Please see F<tests/socketfactory.perl>. It includes SocketFactory samples for every supported socket type.


=back


=back


=back


=back

=head1 Object Layer

This layer puts the O in POE. It's still in development, and this documentation is mostly a place holder.

=over 2

=item 1 Curator

This class manages objects.

=item 2 Object

Instances of this class are managed by the Curator.


=back

=head1 Test and Example Programs

B<The test/example programs have been updated for version 0.06. They even include comments now.>

These example programs may be found in the F<tests> subdirectory. They all should work on any reasonable Perl platform.

=over 2

=item 1 F<followtail.perl>

F<tests/followtail.perl> tests C<Wheel::FollowTail>'s ability to follow files' tails without blocking. It uses write-only ReadWrite wheels to write to logs.

It creates ten sessions that periodically append timestamps to hypothetical log files. It creates ten more sessions to follow those files' tails and display the new timestamps. To ensure that nothing is blocking, it creates a final thread that displays a short message twice every second. Upon SIGINT, they will all shut down, and the temporary log files will be unlinked.

That's 21 cooperative sessions in all.

=item 2 F<forkbomb.perl>

F<tests/forkbomb.perl> verifies parent/child relationships and signal propagation.

It creates 200 sessions whose jobs are to create more of themselves. After the 100th session, sessions will start to randomly exit. After the 200th session, they will stop creating new sessions and all exit. These limits ensure that the program does not take over the machine.

SIGINT should cause the program to exit immediately.

=item 3 F<httpd.perl>

F<tests/httpd.perl> is a simple C<Filter::HTTPD> test.

It creates an HTTP server on port 80 of all interfaces. The port may be overridden on the command line:

  ./httpd.perl 8888

The server should answer and respond to HTTP requests.

=item 4 F<names.perl>

F<tests/names.perl> tests session aliases (formerly known as "names") and provides a simple example of an asynchronous callback protocol for inter-session communication. That's just a fancy way of saying the sessions pass messages back and forth to do blocking things in a nonblocking way.

It creates a "lock daemon" session, and five clients. The clients use the daemon to synchronize their activities. Everything shuts down and exits gracefully on SIGINT.

=item 5 F<objsessions.perl>

F<tests/objsessions.perl> is a version of F<tests/sessions.perl> that uses object sessions instead of inline ones. It's a little simpler than the inline version.

=item 6 F<packagesessions.perl>

F<tests/packagesessions.perl> is a version of F<tests/sessions.perl> that uses package sessions instead of inline ones. It's a little simpler than the inline version.

=item 7 F<preforkedserver.perl>

F<tests/preforkedserver.perl> is a proof of concept for pre-forking servers. It maintains a pool of five servers: one parent (that also handles connections) and four pre- and re-forked children.

=item 8 F<proxy.perl>

F<tests/proxy.perl> is an advanced wheel test that implements a fully-functional port redirector (proxy). It was implemented to make sure that POE was capable of doing it cleanly.

The default redirection table:

  127.0.0.1:7000-127.0.0.1:7001   # cascading proxies on 7000
  127.0.0.1:7001-127.0.0.1:7002
  127.0.0.1:7002-127.0.0.1:7003
  127.0.0.1:7003-127.0.0.1:7004
  127.0.0.1:7004-127.0.0.1:7005
  127.0.0.1:7005-127.0.0.1:7006
  127.0.0.1:7006-127.0.0.1:7007
  127.0.0.1:7007-127.0.0.1:7008
  127.0.0.1:7008-127.0.0.1:7009
  127.0.0.1:7009-perl.org:daytime # plain proxy on 7009
  127.0.0.1:7010-127.0.0.1:7010   # infinite loop-- fun!
  127.0.0.1:7777-127.0.0.1:12345  # test "connection refused"

=item 9 F<refsender.perl> and F<refserver.perl>

F<tests/refserver.perl> is a small reference server. It accepts data from clients and displays some information about it.

F<tests/refsender.perl> is a small reference client. It sends data to a waiting reference server. By default, it sends a few different types of references. When given a numeric parameter, it will send that many copies of C<\@ARGV>. This was added to test POE's ability to handle large, fast streams of data.

B<Please note that refserver and refsender implement a uni-directional protocol. The client does not wait for a response, by design.>

These tests are based on Artur Bergman's contributed code, with ideas from Dave Paris.

=item 10 F<selects.perl>

F<tests/selects.perl> predates wheels. It was written to test POE's basic select logic.

This test creates a chargen server and client in the same process. The client tests its ability to connect and receive information from the server, then shuts down. The server continues to wait for other connections until stopped by SIGINT.

=item 11 F<sessions.perl>

F<tests/sessions.perl> is an early events test. It was modified later to test C<Kernel::call>, making it a little more complicated than its object and package session counterparts.

All the session tests create five sessions, which share the event queue for a small number of iterations before exiting. People who are new to POE might want to look at this test first.

=item 12 F<signals.perl>

F<tests/signals.perl> is an early signals test that was later enhanced to verify sub-second events.

It creates two sessions that wait for signals and display their information. Each session sends fictitious signals to itself, the other session, or the kernel.

SIGINT will gracefully stop the program.

=item 13 F<socketfactory.perl>

F<tests/socketfactory.perl> tests the different types of sockets that C<Wheel::SocketFactory>. It is basically multiple versions of F<thrash.perl>, each using a different socket type, in one program.

=item 14 F<thrash.perl>

F<tests/thrash.perl> stress-tests events, the socket factory, and memory. Its main purpose is to check the Events and I/O layers for memory leaks and flaws. It also acts as a sort of benchmark.

This program creates a simulated daytime server and a pool of clients (5) within the same process. The client pool constantly hits the server with new connections. This program should quickly indicate if POE is leaking resources, and it also seems to be a good profiling target.

The program averages connections per second over ten-second periods. It is not a good example of POE's performance because it is both a server and its own clients. Its benchmarks mainly are used to compare POE's performance from one version to the next.

=item 15 F<tutorial-chat.perl>

F<tests/tutorial-chat.perl> is a very simple chat server. It includes a running narration in blocks of pod. Hopefully it's sufficiently friendly enough to be a useful introduction to POE.

=item 16 F<wheels.perl>

F<tests/wheels.perl> is a version of F<tests/selects.perl> that uses wheels instead of hand-coded event handlers.


=back

=head1 Things To Do

=over 2

=item 1 Near Future

=over 2

=item * fix alarm semantics (need to find a way not to break things)

=back

=item 2 Medium Future

=over 2

=item * Chained filters

=item * Chained wheels

=item * Wrap event handlers in "eval {}", for exception handlers?

=item * Translate die and warn into ... ?

=item * Filter::Block - like Filter::Stream but for datagrams?

=item * Allow Filter::Line to specify the newline character.

=item * Add a Kernel function to list active sessions.

=item * Add a Kernel function to acquire details about a session.

=item * Add a Kernel function to acquire the kernel's and OS's load averages.

=back

=item 3 Ideas to Consider

=over 2

=item * POP? is this POE3 or bholzman's persistent objects?

=item * poe_distributor session, for distributed POE?

=item * $kernel-E<62>stop() and $kernel-E<62>run() to pause and resume the kernel?

=item * Filter::HTTPD needs to send responses directly... POE::Module::*?

=back

=item 4 Someday

=over 2

=item * Use threads, if available, requested and stable.

=item * Use fork, if available and requested.

=item * Distribute event dispatching across several systems.

=item * Load-balancing among distributed POE kernels.

=item * Filter::HTTP (user agent).

=item * Rewrite Serv's curses widgets for POE.

=back


=back

=head1 AUTHORS

=over 2

=item 1 Contributors

These are the people who help make POE possible.

=over 2

=item 1 Artur Bergman

Filter::Reference and Filter::HTTPD are Copyright 1998 Artur Bergman E<60>artur@vogon-solutions.comE<62>. All rights reserved. Artur's contributions are free software; you may redistribute them and/or modify them under the same terms as Perl itself.

=item 2 Dave Paris

Dave Paris's ideas, testing and benchmarking discovered some subtle (and not so subtle) timing problems in POE 0.05. The pre-forking server test was also his idea. Version 0.06 should handle high-load situations much smoother now.

=item 3 Robert Seifer

Robert Seifer contributed probably entirely too much time, both his own and his computer's, to the detection and eradication of a memory corruption bug that POE tickled in Perl. In the end, his work produced a patch that circumvents problems found relating to anonymous subs, scope and @{} processing.


=back

=item 2 Author

POE is Copyright 1998 Rocco Caputo E<60>troc@netrus.netE<62>. All rights reserved. POE is free software; you may redistribute it and/or modify it under the same terms as Perl itself.


=back

=cut
