[Twisted-Python] parallel callbacks? Or inserting into the callback chain?

Is there any way to make a deferred call its callbacks 'in parallel,' or to insert a callback into the callback chain at a point further up than the end? Or maybe there is some other pattern for doing what I need to accomplish, which is getting the result from a deferred before it gets modified by the return of other callbacks that have already been added, but before it is fired. Here is an example that illustrates why I need something like this. It is almost identical to the first example in the deferred howto (http://twistedmatrix.com/projects/core/documentation/howto/defer.html): from twisted.internet import reactor, defer pending = {} def getDummyData(queryName, x): if pending.has_key(x): print "%s piggybacking on pending big expensive query" % queryName return pending[x] d = defer.Deferred() # simulate a delayed result by asking the reactor to fire the # Deferred in 2 seconds time with the result x*3 print "%s about to do some big expensive query" % queryName reactor.callLater(2, d.callback, x*3) pending[x] = d return d def printData(d, queryName): """ Data handling function to be added as a callback: handles the data by printing the result """ print "%s received: %s" % (queryName, d) # simulate two calls (originating from some client[s]) at roughly the same # time for the same query. d = getDummyData('query1',3) d.addCallback(printData,'query1') d = getDummyData('query2',3) d.addCallback(printData,'query2') # manually set up the end of the process by asking the reactor to # stop itself in 13 seconds time reactor.callLater(4, reactor.stop) # start up the Twisted reactor (event loop handler) manually reactor.run() The output, as you might expect, looks like this: query1 about to do some big expensive query thing query2 piggybacking on pending big expensive query thing query1 received: 9 query2 received: None I'd like the output for query2 to match that of query1. Of course, this could be accomplished by adding a 'return d' to the end of printData(), but this is not feasible in this case, because the caller of getDummyData() might have added his own callbacks (in addition to printData()) that do whatever it is that he desires, including changing the return result or not propogating it up the chain. In the scenario I am designing for, getDummyData() will be invoked by client(s), and we don't want to open up new "big expensive" queries to the source if one is already pending that matches. Thus, I'd love for getDummyData() to return a deferred that piggybacks on an existing query, if one that matches is still pending. Can this be done? Is there a way to modify the above [simple] example so that it performs this behavior? Is there some other way to approach the problem that I'm missing? Thanks, Lenny G. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
participants (1)
-
Lenny G Arbage