Running_Pylons_with_Tornado_WSGI_server
<p>Quick introduction, <a href="http://pylonshq.com/" target="_blank">Pylons</a> is a Python web framework that favors flexibility and customization.</p>
<p><a href="http://github.com/facebook/tornado" target="_blank">Tornado</a> is also a web framework (minimal), open sourced by the guys from FriendFeed (they ended up getting bought by Facebook). It comes with asynchronous web server and WSGI server.</p>
<h3>Prerequisites</h3>
<pre><code>
easy_install pylons
easy_install tornado
</code></pre>
<h3>Getting Started</h3>
<p>The harder way to use tornado is through PasteScript. We tried, but was not successful. The easier way is to instantiate PylonsApp object via make_app() on middleware.py</p>
<pre><code>
from paste.deploy import appconfig
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from your_app.config.middleware import make_app
port = 5000
config = appconfig("config:%s" % "/your/app/development.ini")
app = make_app(config.global_conf, **config.local_conf)
# Start the tornado IO loop
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(port)
IOLoop.instance().start()
</code></pre>
<p>That's pretty much it. Get the <a href="http://gist.github.com/468976" target="_blank">gist</a>.</p>
<p>One caveat:</p>
<ul>
<li>When using Tornado, you cannot set <em>debug</em> flag to True.</li>
</ul>
<h3>The basic architecture of Socialinks and how Tornado affect performance</h3>
<p>Here at <a href="../../../recent/">Socialinks</a>, our setup is pretty typical. 4 <a href="http://www.cherrypy.org/wiki/WSGI" target="_blank">CherryPy</a> WSGI servers fronted by Nginx. We replaced those 4 CherryPy with 4 Tornado WSGI servers.</p>
<p>Our caching scheme is quite simple, logged-in vs non-logged-in.Most of non logged in pages are cached using memcache, we cache very minimally on logged in pages. Thus, we are not expecting much performance benefit on typical read-only scenario.</p>
<p>But:</p>
<ul>
<li>Our <em>GET /recent/</em> request time went from 500ms+ to 450ms+ average.</li>
<li>Each CherryPy instance used to consume between 45mb - 95mb of RAM. In comparison, 1 Tornado server hasn't even exceed 50mb of RAM yet.</li>
<li>Overall, the site felt unscientifically faster.</li>
</ul>
<p>We were pleasantly surprised.</p>