How to make anyevent "sequential"?

86 views Asked by At

I would like to try mix of AnyEvent and Coro.
Is there a way to make the three lines between BEGIN and END more elegant/condensed?

use AnyEvent::HTTP;
use Coro;

async {
  _
  # BEGIN
  my $READY = AnyEvent->condvar;
  my $guard = http_request( GET => $url, $READY );
  my ($data, $hHeaders ) = $READY->recv;
  # END
  …
}

WARNING: man AnyEvent suggest slightly different way for Coro integration but the general idea stays the same (comment added after accepted reply).

AnyEvent::HTTP::http_get "url", Coro::rouse_cb;
my ($body, $hdr) = Coro::rouse_wait;
2

There are 2 answers

4
ikegami On BEST ANSWER

Subs. This is what subs are for.

sub sync {
   my $sub = shift;
   $sub = \&$sub;   # Make `strict refs` happy.
   my $done = AnyEvent->condvar;
   my $guard = $sub->( @_, $done );
   return $done->recv;
}

my ( $data, $headers ) = sync \&http_request, GET => $url;
  # -or-
my ( $data, $headers ) = sync http_request => GET => $url;

or

use Sub::Name qw( sub_name );

sub build_sync(_) {
   my $wrapped_sub_name = shift;
   my $wrapped_sub = \&$wrapped_sub_name;

   my $sub_name = $wrapped_sub_name . '_sync';
   my $sub = sub_name $sub_name => sub {
      my $done = AnyEvent->condvar;
      my $guard = $wrapped_sub->( @_, $done );
      return $done->recv;
   };

   no strict qw( refs );
   *$sub_name = $sub;
}

build_sync for qw( http_request ... );

my ( $data, $headers ) = http_request_sync( GET => $url );
0
AnFi On

We can use the following:

sub SYNC (\&@) {
  my $sub = shift @_;
  my $READY =  AnyEvent->condvar;
  my $guard = &$sub( @_, $READY);
  return $READY->recv;
}

my ($data, $hHeaders ) = SYNC &http_request, GET => $url;