POE-Stage
view release on metacpan or search on metacpan
lib/POE/Request.pm view on Meta::CPAN
# requester's original context, somehow.
=head2 return type => RETURN_TYPE, args => \%RETURN_VALUES
return() cancels the current POE::Request object, and returns a
message with an optional RETURN_TYPE and some optional RETURN_VALUES.
The response is encapsulated in a POE::Request::Return object and
automatically sent back to the caller---the POE::Stage that created
the POE::Request that triggered this return().
Please see POE::Request::Return for details about return messages.
The type of message defaults to "return" if not specified.
=cut
sub return {
my ($self, %args) = @_;
# Default return type
$args{type} ||= "return";
$self->_emit("POE::Request::Return", %args);
$self->cancel();
}
=head2 emit type => EMIT_TYPE, args => \%EMIT_VALUES
emit() sends a message to the caller, using an optional EMIT_TYPE and
optional EMIT_VALUES. emit() does not cancel the current transaction,
unlike return(). The response is encapsulated in a POE::Request::Emit
object, and it's automatically sent to the caller.
emit() was created to send back interim or ongoing statuses, possibly
as part of a two-way dialog between a caller and callee.
The type of message defaults to "emit" if not specified.
=cut
sub emit {
my ($self, %args) = @_;
# Default return type
$args{type} ||= "emit";
$self->_emit("POE::Request::Emit", %args);
}
=head2 cancel
Explicitly cancel a request. It's intended for use by the invoked
stage, since the caller is free to destroy its request at any time.
The callee doesn't have that ability, so cancel() grants it
explicitly.
A canceled request cannot generate a response. If you are tempted to
precede cancel() with emit(), then use return() instead. The return()
method is essentially an emit() followed by a cancel().
As mentioned earlier, canceling a request frees up the data associated
with that request. Cancellation and destruction cascade through the
data associated with a request and any sub-stages and sub-requests.
This efficiently and automatically releases all resources associated
with the entire request tree rooted with the canceled request.
For example:
App creates a request for an http client.
HTTP client creates a request for a socket.
Socket factory creates a request for a DNS resolver.
At any point in the hierarchy, a cancellation clears its context and
cancels the lower-level requests. For example, if the App cancels the
HTTP request, the cancelation cascades to the socket factory, and then
to the DNS resolver.
This happens because of one recursive rule: When a request is
canceled, the data members on both sides of the transaction are
destroyed. This only works when stages consistently store subrequests
within their own requests. Here the socket factory request is stored
in the main HTTP fetch request. If the HTTP fetch is canceled before
the socket factory can create a connection, then the socket factory's
request is also canceled.
sub on_http_fetch {
...;
my $req_socket = POE::Request->new(
stage => $socket_factory,
method => "open_socket",
);
This behavior can be nested arbitrarily deep.
=cut
sub cancel {
my $self = shift;
# Cancel all the children first.
foreach my $child (values %{$self->[REQ_CHILD_REQUESTS]}) {
eval {
$child->cancel();
};
}
# A little sanity check. We should have no children once they're
# canceled.
die "canceled parent has children left" if (
keys %{$self->[REQ_CHILD_REQUESTS]}
);
# Disengage from our parent.
# TODO - Use a mutator rather than grope inside the parent object.
if ($self->[REQ_PARENT_REQUEST]) {
my $parent_data = $self->[REQ_PARENT_REQUEST];
delete $parent_data->[REQ_CHILD_REQUESTS]{$self};
$self->[REQ_PARENT_REQUEST] = 0;
}
# Weaken the target stage?
# TODO - Why is this already weak sometimes?
weaken $self->[REQ_TARGET_STAGE];
}
sub _emit {
my ($self, $class, %args) = @_;
# Where does the message go?
# TODO - Have croak() reference the proper package/file/line.
# The message type is important for finding the appropriate method,
# either on the sending stage or its destination.
( run in 1.210 second using v1.01-cache-2.11-cpan-9581c071862 )