NAME
POE::Stage - a proposed base class for formalized POE components
SYNOPSIS
# Note, this is not a complete program.
# See the distribution's examples directory.
my $stage = POE::Stage::Subclass->new();
my $request = POE::Request->new(
stage => $stage, # Invoke this stage
method => "method_name", # calling this method
args => \%parameter_pairs, # with these parameters.
);
DESCRIPTION
TODO - This documentation is out of date.
POE::Stage is a proposed base class for POE components. Its purpose is to standardize the most common design patterns that have arisen through years of POE::Component development.
Complex programs generally perform their tasks in multiple stages. For example, a web request is performed in four major stages: 1. Look up the host's address. 2. Connect to the remote host. 3. Transmit the request. 4. Receive the response.
POE::Stage promotes the decomposition of multi-step processes into discrete, reusable stages. In this case: POE::Stage::Resolver will resolve host names into addresses, POE::Stage::Connector will establish a socket connection to the remote host, and POE::Stage::StreamIO will transmit the request and receive the response.
POE::Stage promotes composition of high-level stages from lower-level ones. POE::Stage::HTTPClient might present a simplified request/response interface while internally creating and coordinating more complex interaction between POE::Stage::Resolver, Connector, and StreamIO. This remains to be seen, however, as POE::Stage is still very new software.
POE stages are message based. The message classes, POE::Request and its subclasses, implement a standard request/response interface for POE stages. Where possible, POE message passing attempts to mimic simpler, more direct calling and returning, albeit asynchronously. POE::Stage and POE::Request also implement closures which greatly simplify asynchronous state management.
RESERVED METHODS
As a base class, POE::Stage must reserve a small number of methods for its own.
new PARAMETER_PAIRS
Create and return a new POE::Stage object, optionally passing key/value PAIRS in its init() callback's $args parameter. Unlike in POE, you must save the object POE::Stage->new() returns if you intend to use it.
It is not recommended that subclasses override new. Rather, they should implement init() to initialize themselves after instantiation.
This may change as POE::Stage implements Class::MOP, Moose, or other Perl 6 ways.
init PARAMETER_PAIRS
init() is a virtual base method used to initialize POE::Stage objects after construction. Subclasses override this to perform their own initialization. The new() constructor will pass its public parameters through to $self->init($key_value_pairs).
Req (attribute)
Defines the Req lexical variable attribute for request closures. Variables declared this way become members of the request the current stage is currently handling.
sub some_handler {
my ($self, $args) = @_;
my $request_field :Req = "some value";
my $sub_request :Req = POE::Request->new(
...,
on_xyz => "xyz_handler"
);
}
Request members are intended to be used as continuations between handlers that are invoked within the same request. The previous handler may eventually pass execution to xyz_handler(), which can access $request_field and $sub_request if the current stage is still handling the current request.
sub xyz_handler {
my ($self, $args) = @_;
my $request_field :Req;
print "$request_field\n"; # "some value"
}
Fields may also be associated with sub-requests being made by the current stage. In this case, variables declared :Rsp within handlers for responses to the associated request will also be visible.
sub some_other_handler {
my ($self, $args) = @_;
my $request_field :Req = "some value";
my $sub_request :Req = POE::Request->new(
...,
on_xyz => "response_handler"
);
my $response_field :Req($sub_request) = "visible in the response";
}
sub response_handler {
my ($self, $args) = @_;
my $request_field :Req;
my $response_field :Rsp;
print "$request_field\n"; # "some value"
print "$response_field\n"; # "visible in the response";
}
Three versions of Req() are defined: One each for scalars, arrays, and hashes. You need not know this since the appropriate one will be used depending on the type of variable declared.
USING
TODO - Describe how POE::Stage is used. Outline the general pattern for designing and subclassing.
DESIGN GOALS
As mentioned before, POE::Stage strives to implement a standard for POE best practices. It embodies some of POE's best and most common design patterns so you no longer have to.
Things POE::Stage does for you:
It manages POE::Session objects so you can deal with truly object-oriented POE::Stages. The event-based gyrations are subsumed and automated by POE::Stage.
It provides a form of message-based continuation so that specially declared variables (using the :Req and :Rsp attributes) are automatically tracked between the time a message is sent and its response arrives. No more HEAPs and tracking request state manually.
It simplifies the call signature of message handlers, eliminating @_ list slices, positional parameters, and mysteriously imported constants (HEAP, ARG0, etc.).
It defines a standardized message class (POE::Request and its subclasses) and a mechanism for passing messages between POE stages. POE::Stage authors won't need to roll their own interface mechanisms, so programmers will not need to learn one for each module in use.
POE::Stage implements object-oriented classes for low-level event watchers. This simplifies POE::Kernel's interface and allows it to be extended celanly. Event watcher ownerships and lifetimes are clearly indicated.
Standardize the means to shut down stages. POE components implement a variety of shutdown methods. POE::Stage objects are shut down by destroying their objects.
It simplifies cleanup when requests are finished. The convention of storing request-scoped data in request continuations means that sub-stages, sub-requests, event watchers, and everything else is automatically cleaned up when a request falls out of scope.
BUGS
See http://thirdlobe.com/projects/poe-stage/report/1 for known issues. See http://thirdlobe.com/projects/poe-stage/newticket to report one.
POE::Stage is too young for production use. For example, its syntax is still changing. You probably know what you don't like, or what you need that isn't included, so consider fixing or adding that. It'll bring POE::Stage that much closer to a usable release.
SEE ALSO
POE::Request is the class that defines inter-stage messages. POE::Watcher is the base class for event watchers, without which POE::Stage won't run very well.
http://thirdlobe.com/projects/poe-stage/ - POE::Stage is hosted here.
http://www.eecs.harvard.edu/~mdw/proj/seda/ - SEDA, the Staged Event Driven Architecture. It's Java, though.
AUTHORS
Rocco Caputo <rcaputo@cpan.org>.
LICENSE
POE::Stage is Copyright 2005-2006 by Rocco Caputo. All rights are reserved. You may use, modify, and/or distribute this module under the same terms as Perl itself.