poetix (old content)

oh build your ship of death

Twisted & Python 2.5

from twisted.internet import defer

def deferredCoroutine(f):

def call(*args, **kwargs):

co = f(*args, **kwargs):

d = co.next()

while 1:

wait = defer.waitForDeferred(d)

yield wait

try:

result = wait.getResult()

err = None

except Exception, e:

result = None

err = e

if err:

d = co.throw(err)

else:

d = co.send(result)

return defer.deferredGenerator(call)

Glyf can turn his nose up at this all he likes, but when you’re scripting a line protocol which goes A sends something to B and waits for B to send something back; B sends something back to B and waits for A to send the next thing; lather, rinse, repeat, it’s really rather nice to be able to write the sequence of things that A does in a single block of continuous code. defer.deferredGenerator offered a slightly clunky way to do this; now that Python 2.5 supports proper coroutines, we can crunch

wait = defer.waitForDeferred(someFunctionReturningADeferred())

yield wait

result = wait.getResult()

into the much more concise and friendly

result = yield someFunctionReturningADeferred()

I think that’s a good thing. A more interesting case would be writing an Asterisk FastAGI script that was also receiving asynchronous event notifications via the Asterisk management interface - there’s an example along these lines in the source of StarPy. In this case, it really would make sense to break everything up into event handlers. (An alternative is to store up the events in a message queue, and pull them off then queue when you feel like processing them - but eventually you end up just dispatching them to handler functions anyway…).

p.s. I have given up trying to persuade WordPress to format Python code correctly - you’ll just have to figure out where the indents go by yourself. Death to all WYSIWTETYSG (What You See Is What The Editor Thinks You Should Get) editors!