AE::postpone degenerates into synchronous behavior, intended?

Michael Alan Dorman mdorman at ironicdesign.com
Mon Dec 31 23:33:28 CET 2012


Hi, Marc,

I was working to patch Stevan Little's recently-released Promises
library to always call callbacks asynchronously when running under
AnyEvent.

It seemed from the documentation that AE::postpone was the idiomatic way
to do what I wanted, but I was surprised to find that nested calls to
AE::postpone degenerated into synchronous behavior, as shown in:

  use AnyEvent;

  my $loop = AE::cv;
  my $ticks = 5;
  my $tick; $tick = AE::timer 0, 0.75, sub {
      print "tick\n";
      unless ($ticks--) {
          undef $tick;
          $loop->send;
      }
  };

  my $postponements = 5;
  my $postponement; $postponement = sub {
      if ($postponements--) {
          AE::postpone {
              print "iter $postponements\n";
              sleep 2;
              $postponement->();
          }
      }
  };
  $postponement->();
  $loop->recv;

which prints:

  tick
  iter 4
  iter 3
  iter 2
  iter 1
  iter 0
  tick
  tick
  tick
  tick
  tick

The behavior I was hoping for can be achieved by replacing $postponement
with:

  my $postponement; $postponement = sub {
      if ($postponements--) {
          my $t; $t = AE::timer 0, 0, sub {
              print "iter $postponements\n";
              sleep 2; undef $t;
              $postponement->();
          }
      }
  };

which prints:

  tick
  iter 4
  iter 3
  tick
  tick
  iter 2
  tick
  iter 1
  tick
  iter 0
  tick

Looking at the code, it is clear to me why the difference in behavior
exists, but seems to me that it if it is the behavior that is intended,
it should be documented that nested calls to AE::postpone will behave
synchronously...otherwise I'm happy to attempt to attempt a fix.

Thoughts?

Mike.



More information about the anyevent mailing list