[Twisted-Python] Re: Adding callback to a Deferred that's already running?

David Bolen db3l at fitlinxx.com
Thu Aug 26 12:26:13 MDT 2004

Abe Fettig <abe at fettig.net> writes:

> Steve,
> I'm all too familar with the situation you describe, and I've come up
> with a pattern that works well for me.  Here's how I would have
> written your example:
> class XMLRPCResponseClass():
>      def step1(self):
> 	finished = defer.Deferred()
> 	self.db.runQuery(blah).addCallback(
>              self.step2, finished).addErrback(finished.errback)
>          return finished
>      def step2(self, result, finished):
>          if result == 'yadda':
>              finished.callback('This bit works')
>          else:
>              self.d.runOperation(blah).chainDeferred(finished)

I'm not sure I follow the need for the extra deferred.  I would think
that the following would work just as well:

    class XMLRPCResponseClass():

         def step1(self):
            return self.db.runQuery(blah).addCallback(self.step2)

         def step2(self, result):
             if result == 'yadda':
                 return 'This bit works'
                 return self.db.runOperation(blah)

In this case, the primary deferred is the original runQuery.  The
first callback on that forwards you to step 2.  A failure would flow
up the errback chain which you don't process locally but leave to the
caller to handle.

In the success case, if you need to additionally process the result
you just return the new value (the 'yadda' test), otherwise you spin
off another deferred operation, returning that deferred from your
callback.  Returning a deferred within a callback is an implicit
chaining operation as Twisted will wait for that new deferred to
finish before taking its result and propagating it up the callback or
errback chain appropriately.

Remember that when you add your callbacks/errbacks you are in control
of the sequence of execution as the callback/errback chain fires, and
thus you'll always get control in advance of any other
callback/errbacks that callers who you return the same deferred to
might be attaching.  That, plus the implicit chaining Twisted permits
by an individual function in the callback/errback chain itself
returning a deferred is pretty flexible.  It's certainly been rare for
me to need my own internally generated deferred unless I was the root
of the deferrable operation.

-- David

More information about the Twisted-Python mailing list