Pardon my misreading...

Michael Alan Dorman mdorman at ironicdesign.com
Wed Jan 2 16:23:13 CET 2013


Darin McBride <darin.mcbride at shaw.ca> writes:
> For example, using the SYNOPSIS as on github, the "then" method would
> call AE::postpone when each fetch completed, if I'm reading this
> right, which is possibly all in a single loop of the event loop, but
> unlikely.  And, if it is, they will all be handled at the end of the
> current loop, and then you move on.  I don't see why these should be
> called recursively.

I believe the benefit of Promises over most other styles of async coding
(and which I think Stevan's examples don't do enough to emphasize) is
that they are compositional.

So you do things like:

   my $promise = do_something_async;
   $promise->then (sub {my ($a) = @_; $b = f($a)})
           ->then (sub {my ($b) = @_; $c = f($b)})
           ->then (sub {my ($c) = @_; $d = f($c)});

With the Promises code as it currently exists, that string of ->then()s
will be processed synchronously.  And it happens that it is handled
recursively because each ->then is returning a new promise, so each
parent invokes its children and so on.

My desire was to try and specialize the code that handles fulfilling the
promises to give the event loop an opportunity to run between steps, in
order to increase throughput for the overall system at the cost of some
latency for long chains of promises.  This would mean that even
relatively heavyweight processing of results---assuming they were
amenable to pipeline-style-processing---could have lower impact on
system throughput.

I did this initially by just wrapping the invocation for the ->then()
callbacks with AE::postpone.  And this seemed to work fine in my first,
simplest, test.

However, the moment I had two steps, they would both run to completion
before the event loop ran again because the recursive invocation of
postpone (remember, the cascade of promises is effectively handled
recursively)---so that was no better than the original behavior.

> Sorry, I'm missing the distinction.  AE::postpone simply is a deferral
> to the end of the *current* loop, and if you're in one postpone,
> you're already at the end of the loop, so it'll run the next one
> immediately in the current loop.

I gather I assigned too much weight to the "or shortly afterward" clause
in the docs---perhaps a result of the behavior I witnessed when I only
did one postpone per event, where the event loop *did* have a chance to
run.

> Note that you can implement a similar postpone function that works the way you 
> want (I think) easily enough. [...]
> But I don't think this saves much over using AE::timer 0, 0, sub {...} 
> directly.

I agree.

> And, as I said, I'm not sure of a non-.t use case that this is an issue for.  
> Or maybe I still don't really understand the issue.

I was just barking up the wrong tree with regards to postpone, I think.
I misread the documentation, which, as Marc has said, lays out a precise
definition of what it does.

Anyway, Darin, I really appreciate your patience and help.  I understand
now that I made an incorrect understanding of postpone's intent, and
will need to use a different strategy.

Mike.



More information about the anyevent mailing list