[Twisted-Python] chaining deferreds

Dorian Raymer deldotdr at gmail.com
Thu Jun 19 17:23:16 EDT 2008

Hi Andy,
Your example code is very close to working. The reason the chain didn't
proceed as you expected is because the callbacks of the second
Deferredcreated in the function
print_something were never triggered to run.

You need to keep track of what actually triggers a deferred's callback chain
to run and what each of the callback functions return.
In practice, that second deferred could have been replaced by some
asynchronous function that actually returned a deferred, and your code would
have worked.

The simplest change to make you code work is to change print_something to

def print_something(x):
    print "printing: ", x
    d = defer.Deferred()
    d.addCallbacks(do_something_inbetween, oops)
    d.callback("printed something")
    return d
Doing this is kind of redundant though, because in this case it is
equivalent to:

def print_something(x):
    print "printing: ", x
    return do_something_inbetween('printed_something')

Another thing you can do instead of creating a new deferred is wrap the call
to do_something_inbetween with defer.maybeDeferred. This is convenient
because if do_something_inbetween does not return a deferred (which is the
case here), then maybeDeferred will do this for you.

Here's an example (a slight modification of your original) that includes
calling a function that returns a deferred and using maybeDeferred to
construct a deferred chain.

from twisted.internet import reactor, defer

def do_something_inbetween(x):
    print "doing something else: ", x
    return "done something else"

def print_something(x):
    print "printing: ", x
    d = defer.maybeDeferred(do_something_inbetween,'printed something')
    d.addCallbacks(finish_up, oops)
    return d

def finish_up(x):
    print "finishing up with: ", x

def oops(e):
    print str(e)

def go():
    print "constructed deferred"
    d = defer.Deferred()
    return d

def extra(r):
    print 'extra', r
    return r

d = go()
reactor.callLater(1, d.callback, "hello mr")
reactor.callLater(5, reactor.stop)
print "setup everything"

Hope that helps.

On Wed, Jun 18, 2008 at 11:39 PM, Andy Hird <andyhird at gmail.com> wrote:

> Hi all,
> I've been trying to get a really basic example of chaining deferreds going
> with no luck. I was hoping someone could give me some help and tell me where
> I'm going wrong.
> I've attached the basic code to this message.
> I'd expect output to be:
> constructed deferred
> setup everything
> printing:  hello mr
> doing something else: printed something
> finishing up with: done something else
> But instead the callback chain stops after print_something() has been
> called (do_something inbetween and finish_up are never called).
> Thanks for any help in advance!
> Andy Hird
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://twistedmatrix.com/pipermail/twisted-python/attachments/20080619/4317ae18/attachment.htm 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tw2extra.py
Type: text/x-python
Size: 747 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20080619/4317ae18/attachment.py 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tw2-1.py
Type: text/x-python
Size: 650 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20080619/4317ae18/attachment-0001.py 

More information about the Twisted-Python mailing list