AnyEvent-Future
view release on metacpan or search on metacpan
lib/AnyEvent/Future.pm view on Meta::CPAN
my $url = ...;
my $f = as_future_cb {
my ( $done_cb ) = @_;
http_get $url, $done_cb;
};
This could of course be easily wrapped by a convenient function to return
futures:
sub http_get_future
{
my ( $url, @args ) = @_;
as_future_cb {
my ( $done_cb ) = @_;
http_get $url, @args, $done_cb;
}
}
=head2 Using C<Future>s as enhanced C<CondVar>s
While at first glance it may appear that a C<Future> instance is much like an
L<AnyEvent::CondVar>, the greater set of convergence methods (such as
C<needs_all> or C<needs_any>), and the various utility functions (in
L<Future::Utils>) makes it possible to write the same style of code in a more
concise or powerful way.
For example, rather than using the C<CondVar> C<begin> and C<end> methods, a
set of C<CondVar>-returning functions can be converted into C<Futures>,
combined using C<needs_all>, and converted back to a C<CondVar> again:
my $cv = Future->needs_all(
Future::AnyEvent->from_cv( FUNC1() ),
Future::AnyEvent->from_cv( FUNC2() ),
...
)->as_cv;
my @results = $cv->recv;
This would become yet more useful if, instead of functions that return
C<CondVars>, we were operating on functions that return C<Future>s directly.
Because the C<needs_all> will cancel any still-pending futures the moment one
of them failed, we get a nice neat cancellation of outstanding work if one of
them fails, in a way that would be much harder without the C<Future>s. For
example, using the C<http_get_future> function from above:
my $cv = Future->needs_all(
http_get_future( "http://url-1" ),
http_get_future( "http://url-2" ),
http_get_future( "https://url-third/secret" ),
)->as_cv;
my @results = $cv->recv;
In this case, the moment any of the HTTP GET functions fails, the ones that
are still pending are all cancelled (by dropping their cancellation watcher
object) and the overall C<recv> call throws an exception.
Of course, there is no need to convert the outermost C<Future> into a
C<CondVar>; the full set of waiting semantics are implemented on these
instances, so instead you may simply call C<get> on it to achieve the same
effect:
my $f = Future->needs_all(
http_get_future( "http://url-1" ),
...
);
my @results = $f->get;
This has other side advantages, such as the list-valued semantics of failures
that can provide additional information besides just the error message, and
propagation of cancellation requests.
=cut
=head1 TODO
=over 4
=item *
Consider whether or not it would be considered "evil" to inject a new method
into L<AnyEvent::CondVar>; namely by doing
sub AnyEvent::CondVar::as_future { AnyEvent::Future->from_cv( shift ) }
=back
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;
( run in 0.725 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )