Tomorrow I&#39;m giving a talk to provide an introduction to asynchronous programming.  I&#39;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&#39;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&#39;d expected I&#39;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__ == &#39;__main__&#39;:</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&#39;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 &lt;twisted.protocols.policies.ThrottlingFactory instance at 0x1016497e8&gt;</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 &quot;slow_server.py&quot;, line 16, in &lt;module&gt;</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 &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py&quot;, 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 &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py&quot;, 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>--- &lt;exception caught here&gt; ---</font></div>

</div><div><div><font face="courier new, monospace"><span style="white-space:pre-wrap">        </span>  File &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py&quot;, 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 &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py&quot;, 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 &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py&quot;, 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 &quot;/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/protocols/policies.py&quot;, 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: &#39;NoneType&#39; object has no attribute &#39;pauseProducing&#39;</font></div>

</div></blockquote><div><br></div><div><br></div><div>I&#39;m sure it&#39;s not impossible to figure out what I need to do here, but I&#39;d appreciate any pointers.</div><div><br></div><div>Many thanks in advance!</div>