import stackless from twisted.internet import defer def deferredTasklet(func): """ I'm a function decorator that makes a stacklessy-function (one that might 'block', etc) into one that returns a Deferred for integrating with Twisted. XXX: Do a hack so the name of 'replacement' is the name of 'func'. """ def replacement(*args, **kwargs): d = defer.Deferred() def tasklet(*args, **kwargs): try: d.callback(func(*args, **kwargs)) except: d.errback() print "hey, I just callbacked or errbacked." print "task...", func.__name__ crap = stackless.tasklet(tasklet)(*args, **kwargs) crap.run() print "...let", func.__name__, crap return d return replacement def blockOn(d): """ Use me in stacklessy-code to wait for a Deferred to fire. XXX: If the result is an failure, raise its exception. """ ch = stackless.channel() def cb(r): print "blockOnCB", r ch.send(r) d.addBoth(cb) return ch.receive() def TEST(): """ Show off deferredTasklet and blockOn. """ from twisted.internet import reactor import time #let's make sure we're not blocking anywhere def timer(): print "time!", time.time() reactor.callLater(0.5, timer) reactor.callLater(0, timer) def getDeferred(): d = defer.Deferred() reactor.callLater(3, d.callback, 'goofledorf') print "blocking on", d r = blockOn(d) print "got", r, "from blocking" return r getDeferred = deferredTasklet(getDeferred) # below is our 'legacy' Twisted code that only knows about # Deferreds, not crazy stackless stuff. print "getDeferred is", getDeferred d = getDeferred() print "d is", d def _cbJunk(r): print "RESULT", r reactor.stop() d.addCallback(_cbJunk) print "kicking it off!" reactor.run() if __name__ == '__main__': TEST()