[Twisted-Python] Re: Making DeferredList look like Deferred

Lenny G Arbage alengarbage at yahoo.com
Mon Feb 6 16:23:39 EST 2006

Thomas HERVE therve at free.fr wrote:
> But really, I don't see the point of this. 
> If you want to have an exception somewhere,
> use fireOnOneErrback. Else there's no need
> to build the result list, if you're
> actually raising an Exception for *one*
> error.

  What if the desired exception handling should occur
*after* all the Deferreds have fired, regardless of
whether they fired err or callback?

  This is particularly useful for p2p-style apps.  For
example, suppose I want to maintain a maximum of 20
outstanding requests for a given operation -- I don't
want to spin off another 20 (or another X) until I
know exactly how many of the original 20 failed and
how many succeeded.  (This type of operation is
common, for instance, when you are doing erasure
coding or shamir secret sharing, where you really only
need Y out of Z requests to succeed, but where you do
need to respawn W new requests if you didn't get Y
after the first round.)
  fireOnOneErrback doesn't seem to give me that
functionality -- it gets fired only once, for the
first failure.  I don't know which other of the 20
requests failed or will fail, and there may be
outstanding requests that will yet succeed that I'll
never learn about.

  I think I'm beginning to see, though, that this is
all accounted for by just letting the DeferredList's
callback get invoked, and wrapping it similarly to
what you posted.  My only complaint, as you pointed
out, is that this seems a bit clumsy.

  However, cluttering up the API with another special
flag to handle my border case where I want the
DeferredList's errback to be invoked just like the
callback, but only if => 1 of its Deferreds
errback'ed, may be even worse.  It sure would be handy
for me, however, so I'll likely create my own
SpecialDeferredList that does the wrapping behind the
scenes and fires the back() that I expect.

  Unless, of course, there is a better way.  Here's
what I'm currently using to wrap:

def DeferredListToDeferred(result):
    print " result was: %s" % result
    for code, res in result:
        if code == False:
            # assumes failed results have 
            # (False, failure) pairs, and
            # only returns the first of
            # these.
            return res
    return result

Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 

More information about the Twisted-Python mailing list