
Abe Fettig <abe@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' else: 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