NAME

    AnyEvent::Future - use Future with AnyEvent

SYNOPSIS

       use AnyEvent;
       use AnyEvent::Future;
    
       my $future = AnyEvent::Future->new;
    
       some_async_function( ..., cb => sub { $future->done( @_ ) } );
    
       print Future->wait_any(
          $future,
          AnyEvent::Future->new_timeout( after => 10 ),
       )->get;

    Or

       use AnyEvent::Future qw( as_future_cb );
    
       print Future->wait_any(
          as_future_cb {
             some_async_function( ..., cb => shift )
          },
          AnyEvent::Future->new_timeout( after => 10 ),
       )->get;

DESCRIPTION

    This subclass of Future integrates with AnyEvent, allowing the await
    method to block until the future is ready. It allows AnyEvent-using
    code to be written that returns Future instances, so that it can make
    full use of Future's abilities, including Future::Utils, and also that
    modules using it can provide a Future-based asynchronous interface of
    their own.

    For a full description on how to use Futures, see the Future
    documentation.

CONSTRUCTORS

 new

       $f = AnyEvent::Future->new

    Returns a new leaf future instance, which will allow waiting for its
    result to be made available, using the await method.

 new_delay

       $f = AnyEvent::Future->new_delay( @args )

 new_timeout

       $f = AnyEvent::Future->new_timeout( @args )

    Returns a new leaf future instance that will become ready at the time
    given by the arguments, which will be passed to the AnyEvent->timer
    method.

    new_delay returns a future that will complete successfully at the
    alotted time, whereas new_timeout returns a future that will fail with
    the message Timeout. This is provided as a simple utility for small
    use-cases; for a more find-grained control over the failure message and
    additional values you may wish to use new_delay combined with the
    then_fail method:

       new_delay( after => 10 )
          ->then_fail( "The operation timed out after 10 seconds", timeout => );

 from_cv

       $f = AnyEvent::Future->from_cv( $cv )

    Returns a new leaf future instance that will become ready when the
    given AnyEvent::CondVar instance is ready. The success or failure
    result of the future will be the result passed to the condvar's send or
    croak method.

METHODS

 as_cv

       $cv = $f->as_cv

    Returns a new AnyEvent::CondVar instance that wraps the given future;
    it will complete with success or failure when the future does.

    Note that because AnyEvent::CondVar->croak takes only a single string
    message for the argument, any subsequent failure detail values from the
    future are lost by the condvar. To capture these as well, you may wish
    to use an on_fail callback or the failure method, to obtain them.

UTILITY FUNCTIONS

    The following utility functions are exported as a convenience.

 as_future

       $f = as_future { CODE }

    Returns a new leaf future instance, which is also passed in to the
    block of code. The code is called in scalar context, and its return
    value is stored on the future. This will be deleted if the future is
    cancelled.

       $w = CODE->( $f )

    This utility is provided for the common case of wanting to wrap an
    AnyEvent function which will want to receive a callback function to
    inform of completion, and which will return a watcher object reference
    that needs to be stored somewhere.

 as_future_cb

       $f = as_future_cb { CODE }

    A futher shortcut to as_future, where the code is passed two callback
    functions for done and fail directly, avoiding boilerplate in the
    common case for creating these closures capturing the future variable.
    In many cases this can reduce the code block to a single line.

     $w = CODE->( $done_cb, $fail_cb )

EXAMPLES

 Wrapping watcher-style AnyEvent functions

    The as_future_cb utility provides an excellent wrapper to take the
    common style of AnyEvent function that returns a watcher object and
    takes a completion callback, and turn it into a Future that can be used
    or combined with other Future-based code. For example, the
    AnyEvent::HTTP function called http_get performs in this style.

       use AnyEvent::Future qw( as_future_cb );
       use AnyEvent::HTTP qw( http_get );
    
       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;
          }
       }

 Using Futures as enhanced CondVars

    While at first glance it may appear that a Future instance is much like
    an AnyEvent::CondVar, the greater set of convergence methods (such as
    needs_all or needs_any), and the various utility functions (in
    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 CondVar begin and end methods, a set
    of CondVar-returning functions can be converted into Futures, combined
    using needs_all, and converted back to a 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
    CondVars, we were operating on functions that return Futures directly.
    Because the 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
    Futures. For example, using the 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 recv call throws an
    exception.

    Of course, there is no need to convert the outermost Future into a
    CondVar; the full set of waiting semantics are implemented on these
    instances, so instead you may simply call 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.

TODO

      * Consider whether or not it would be considered "evil" to inject a
      new method into AnyEvent::CondVar; namely by doing

         sub AnyEvent::CondVar::as_future { AnyEvent::Future->from_cv( shift ) }

AUTHOR

    Paul Evans <leonerd@leonerd.org.uk>

