The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AE::AdHoc - Simplified interface for tests/examples of AnyEvent-related code.

SYNOPSIS

Suppose we need to test some AnyEvent-related code. To avoid hanging up, we add a timeout. The resulting code is like:

    use AnyEvent;
    my $cv = AnyEvent->condvar;
    my $timer = AnyEvent->timer(
        after => 10, cb => sub { $cv->croak("Timeout"); }
    );
    do_something(
        sub{ $cv->send(shift); }, sub{ $cv->croak(shift); }
    );
    my $result = $cv->recv();
    undef $timer;
    analyze_do_something( $result );

Now, the same with AE::AdHoc:

    use AE::AdHoc;

    my $result = ae_recv {
         do_something( ae_send, ae_croak );
    } 10; # timeout
    analyze_do_something( $result );

EXPORT

Functions ae_recv, ae_send, ae_croak, ae_begin, ae_end, and ae_goal are exported by default.

SUBROUTINES

Note: Anywhere below, $cv means AnyEvent's conditional variable responsible for current event loop. See condvar section of AnyEvent.

ae_recv { CODE; } [ $timeout ] %options;

The main entry point of the module.

Run CODE block, enter event loop and wait for $timeout seconds for callbacks set up in CODE to fire, than die. Return whatever was sent via ae_send.

$timeout must be a nonzero real number. Negative value means "run forever". $timeout=0 would be ambigous, so it's excluded.

Options may include:

  • timeout - override the $timeout parameter (one timeout MUST be present).

  • soft_timeout - Override $timeout, and don't die, but return undef instead.

Other functions in this module would die if called outside of ae_recv.

ae_send ( [@fixed_args] )

Create callback for normal event loop ending.

Returns a sub that feeds its arguments to $cv-send()>. Arguments given to the function itself are prepended, as in $cv-send(@fixed_args, @callback_args)>.

NOTE that ae_recv will return all sent data "as is" in list context, and only first argument in scalar context.

May be called as ae_send->( ... ) if you want to stop event loop immediately (i.e. in a handcrafted callback).

ae_croak ( [$fixed_error] )

Create callback for event loop termination.

Returns a sub that feeds its first argument to $cv->croak(). If argument is given, it will be used instead.

ae_begin ( [ sub { ... } ] )

ae_end

These subroutines provide ability to wait for several events to complete.

The AnyEvent's condition variable has a counter that is incremented by begin() and decreased by end(). Optionally, the begin() function may also set a callback.

Whenever the counter reaches zero, either that callback or just send() is executed on the condvar.

Note: If you do provide callback and want the event loop to stop there, consider putting ae_send->( ... ) somewhere inside the callback.

Note: ae_begin() acts at once, and does NOT return a closure. ae_end, however, returns a subroutine reference just like ae_send/ae_croak do.

See begin/end section in AnyEvent.

ADVANCED MULTIPLE GOAL INTERFACE

ae_goal( "name", @fixed_args )

Create a named callback.

When callback is created, a "goal" is set.

When such callback is called, anything passed to it is saved in a special hash as array reference (prepended with @fixed_args, if any).

When all goals are completed, the hash of results is returned by ae_recv.

If ae_send is called at some point, the list of incomplete and complete goals is still available via goals and results calls.

The goals and results are reset every time upon entering ae_recv.

AE::AdHoc->goals

Return goals not yet achieved as hash ref.

AE::AdHoc->results

Return results of completed goals as hash ref.

ADDITIONAL ROUTINES

ae_action { CODE } %options

Perform CODE after entering the event loop via ae_recv (a timer is used internally).

CODE will NOT run after current event loop is terminated (see ae_recv).

CAVEATS

This module is still under heavy development, and is subject to change. Feature/change requests are accepted.

Callback confinement

If event loop is entered several times, the callbacks created in one invocations will NOT fire in another. Instead, they'll issue a warning and return (see "Error handling" below).

Error message will be like ae_send at file:13 from ae_recv[1] at file:12 called in ae_recv[2] at file:117

This is done so to isolate invocations as much as possible.

However, detection of "this invocation" will go wrong if callback maker is called in a callback itself. For instance, this will always work the same:

        # ...
        callback => sub { ae_send->(@_); },
        # ...

Error handling

Dying within event loop is a bad idea, so we issue warnings and write errors to magic variables. It is up to the user to check these variables.

  • $AE::AdHoc::errstr - last error (as in ::DBI).

  • @AE::AdHoc::errors - all errors.

  • $AE::AdHoc::warnings - set this to false to suppress warnings.

AUTHOR

Konstantin S. Uvarin, <khedin at gmail.com>

BUGS

Please report any bugs or feature requests to bug-ae-adhoc at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=AE-AdHoc. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc AE::AdHoc

You can also look for information at:

SEE ALSO

AnyEvent

ACKNOWLEDGEMENTS

LICENSE AND COPYRIGHT

Copyright 2012 Konstantin S. Uvarin.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.