[Twisted-Python] Multiple deferreds that depend on each other

Reza Lotun rlotun at gmail.com
Tue Nov 17 11:08:22 EST 2009


Hi Landreville,

> If I want to do a number of actions in a row that each return a deferred but
> depend on eachother, do I need to nest those callbacks?
> Ie if i want to:
> 1. Call database function using adbabi
> 2. Call xmlrpc method using result from 1
> 3. Call database using result from 2
> Would I just put 2 inside the callback for 1 and then put 3 inside the
> callback for 2?

By multiple deferreds that depend on each other, you probably mean a
linear firing of actions based on callbacks of previous actions. The
only way to do that is to trigger actions in callbacks of the
deferreds in question, as you allude to.

Yeah, so roughly something like this would work:

def db_call(arg):
   dfr = make_db_call_in_thread(arg)
   return dfr

def xmlrpc_call(arg):
   dfr = make_call(arg)
   return dfr

dfr = db_call(some_initial_arg)
dfr.addCallback(xmlrpc)
dfr.addCallback(db_call)

> How would I do that in one function? All the examples I have seen have a
> function calling one method returning a deferred and then placing the logic
> (doing something with the result) in the callback, but do not deal with
> multiple deferreds that depend on each other.

To do it in one function, you could use something like:

def complex_call():
    def db_call(arg):
       dfr = make_db_call_in_thread(arg)
       return dfr

    def xmlrpc_call(arg):
       dfr = make_call(arg)
       return dfr

    dfr = db_call(some_initial_arg)
    dfr.addCallback(xmlrpc_call)
    dfr.addCallback(db_call)
    dfr.addErrback(my_errback_handler)
    return dfr

Or you can make each handler a method on a class. Another way to do it
is to use inlineCallbacks:

from twisted.internet import defer
@defer.inlineCallbacks
def example():
    res = yield db_call(some_initial_arg)
    rpc_res = yield xmlrpc_call(res)
    db_res = yield db_call(rpc_res)

In the above example, it's all still asynchronous (if not parallel),
but it looks like it's synchronous, using the magic of decorators and
Python 2.5+'s ability to retrieve results from yield statements.

Hope that makes sense.

Cheers,
Reza

-- 
Reza Lotun
mobile: +44 (0)7521 310 763
email:  rlotun at gmail.com
work:   reza at tweetdeck.com
twitter: @rlotun



More information about the Twisted-Python mailing list