Tomorrow I'm giving a talk to provide an introduction to asynchronous programming. I'll be mentioning Twisted in passing, but the meat of the talk will be about writing a web crawler for finding broken links, first using single-threaded blocking code, then multi-threaded blocking code, before demonstrating a non-blocking solution using a select loop. I can make the code and slides available if there's interest.<div>
<br></div><div>For this to be effective, I was planning on writing a very slow webserver to serve static content locally. I'd expected I'd be able to simply wrap an instance of twisted.web.static.Site in a ThrottlingFactory, and serve away:</div>
<div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="courier new, monospace">import sys</font></div></div><div><div><font face="courier new, monospace"><br></font></div></div>
<div><div><font face="courier new, monospace">from twisted.internet import reactor</font></div></div><div><div><font face="courier new, monospace">from twisted.internet.endpoints import TCP4ServerEndpoint</font></div></div>
<div><div><font face="courier new, monospace">from twisted.protocols.policies import ThrottlingFactory</font></div></div><div><div><font face="courier new, monospace">from twisted.web.server import Site</font></div></div>
<div><div><font face="courier new, monospace">from twisted.web.static import File</font></div></div><div><div><font face="courier new, monospace">from twisted.python import log</font></div></div><div><div><font face="courier new, monospace"><br>
</font></div></div><div><div><font face="courier new, monospace">if __name__ == '__main__':</font></div></div><div><div><font face="courier new, monospace"> log.startLogging(sys.stdout)</font></div></div><div>
<div>
<font face="courier new, monospace"> resource = File(sys.argv[1])</font></div></div><div><div><font face="courier new, monospace"> factory = Site(resource)</font></div></div><div><div><font face="courier new, monospace"> endpoint = TCP4ServerEndpoint(reactor, 4321)</font></div>
</div><div><div><font face="courier new, monospace"> endpoint.listen(ThrottlingFactory(factory, maxConnectionCount=3, readLimit=20, writeLimit=20))</font></div></div><div><div><font face="courier new, monospace"> reactor.run()</font></div>
</div></blockquote><div><br></div><div><br></div><div>However, this fails with the following error because I've not registered a producer with my ThrottlingProtocol:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px">
<div><div><font face="courier new, monospace">2012-11-05 21:01:34+0000 [-] Throttling writes on <twisted.protocols.policies.ThrottlingFactory instance at 0x1016497e8></font></div></div><div><div><font face="courier new, monospace">2012-11-05 21:01:34+0000 [-] Unhandled Error</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span>Traceback (most recent call last):</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "slow_server.py", line 16, in <module></font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> reactor.run()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py", line 1169, in run</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> self.mainLoop()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py", line 1178, in mainLoop</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> self.runUntilCurrent()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span>--- <exception caught here> ---</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py", line 800, in runUntilCurrent</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> call.func(*call.args, **<a href="http://call.kw" target="_blank">call.kw</a>)</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py", line 290, in checkWriteBandwidth</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> self.throttleWrites()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py", line 324, in throttleWrites</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> p.throttleWrites()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py", line 221, in throttleWrites</font></div>
</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span> self.producer.pauseProducing()</font></div></div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span>exceptions.AttributeError: 'NoneType' object has no attribute 'pauseProducing'</font></div>
</div></blockquote><div><br></div><div><br></div><div>I'm sure it's not impossible to figure out what I need to do here, but I'd appreciate any pointers.</div><div><br></div><div>Many thanks in advance!</div>