A while ago I wrote about Defgen, which lets you use generator syntax to write Python code in a “blocking” format. I thought it was pretty cool, but it required some strange backflips to work right.
Yesterday, Glyph showed me something that was added to Twisted trunk a little while ago: inlineCallbacks. It’s the same concept, but because it uses the new yield syntax in Python 2.5, it’s even prettier.
Here’s the current source from doc/core/examples/ampclient.py:
from twisted.internet import reactor, defer
from twisted.internet.protocol import ClientCreator
from twisted.protocols import amp
from ampserver import Sum, Divide
def doMath():
d1 = ClientCreator(reactor, amp.AMP).connectTCP(
'127.0.0.1', 1234).addCallback(
lambda p: p.callRemote(Sum, a=13, b=81)).addCallback(
lambda result: result['total'])
def trapZero(result):
result.trap(ZeroDivisionError)
print “Divided by zero: returning INF”
return 1e1000
d2 = ClientCreator(reactor, amp.AMP).connectTCP(
‘127.0.0.1′, 1234).addCallback(
lambda p: p.callRemote(
Divide,
numerator=1234,
denominator=0)
).addErrback(trapZero)
def done(result):
print ‘Done with math:’, result
defer.DeferredList([d1, d2]).addCallback(done)
Here’s what it looks like using inlineCallbacks:
@defer.inlineCallbacks
def doMath():
client = ClientCreator(reactor, amp.AMP)
conn = yield client.connectTCP('127.0.0.1', 1234)
sumResult = (yield conn.callRemote(Sum, a=13, b=81))['total']
try:
divideResult = yield conn.callRemote(
Divide, numerator=1234, denominator=0)
except ZeroDivisionError:
print “Divided by zero: returning INF”
divideResult = 1e1000
result = [sumResult, divideResult]
print ‘Done with math:’, result
defer.returnValue(result)
It’s infinitely more legible. I’ve always hated the process of writing callback-driven procedures, just because the code no longer flows top-to-bottom. Even a simple client-side operation gets mangled (like above). But with inlineCallbacks, your code looks totally synchronous; it’s just executed asynchronously.
Too bad it’s only usable on Python 2.5. That means only Twisted-based applications can use it; the Twisted library itself won’t shed backwards-compatibility for a long time.
![[ Hacker ]](/static/images/hacker.png)
Leave a Reply