<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>geek scrap &#187; supervisord</title>
	<atom:link href="http://geekscrap.com/tags/supervisord/feed/" rel="self" type="application/rss+xml" />
	<link>http://geekscrap.com</link>
	<description>there is at least one way to do it</description>
	<lastBuildDate>Tue, 12 Apr 2011 10:14:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Integrate Tornado in Django</title>
		<link>http://geekscrap.com/2010/02/integrate-tornado-in-django/</link>
		<comments>http://geekscrap.com/2010/02/integrate-tornado-in-django/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:32:00 +0000</pubDate>
		<dc:creator>geekscrap</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[How-tos]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[supervisord]]></category>
		<category><![CDATA[tornado]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://geekscrap.com/?p=588</guid>
		<description><![CDATA[Tornado is a nice python WSGI-compliant web server developed by guys at FriendFeed. It&#8217;s primarily thought as application server for python web frameworks and according to FriendFeed benchmarks, it&#8217;s blazing fast thanks to its non-blocking connections. UPDATE: For more performance info, James Abley pointed me to a very complete benchmark of available Python asynchronous webservers. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tornadoweb.org/">Tornado</a> is a nice python WSGI-compliant web server developed by guys at FriendFeed. It&#8217;s primarily thought as application server for python web frameworks and according to FriendFeed benchmarks, it&#8217;s blazing fast thanks to its non-blocking connections.</p>
<p><strong>UPDATE</strong>: For more performance info, James Abley pointed me to a <a rel="nofollow" href="http://nichol.as/asynchronous-servers-in-python">very complete benchmark</a> of available Python asynchronous webservers. It looks like Tornado is a real monster of concurrency.</p>
<p>There are already some how-to&#8217;s on the web on plugging Django web framework into Tornado webserver. A quick recap:</p>
<ol>
<li>A <a rel="nofollow" href="http://www.jeremybowers.com/blog/4/tornado-web-framework-production-django-and-nginx/">tutorial</a> on Tornado, Django and nginx by Jeremy Bowers.</li>
<li>How to <a rel="nofollow" href="http://lincolnloop.com/blog/2009/sep/15/using-django-inside-tornado-web-server/">import django framework</a> inside a Tornado project by Lincoln Loop.</li>
<li>A <a rel="nofollow" href="http://www.djangosnippets.org/snippets/1748/">snippet</a> by lawgon.</li>
</ol>
<p>My approach is slightly different as I wanted to run Tornado using Django management command-line interface.</p>
<p><span id="more-588"></span>The 3 easy steps are:</p>
<ol>
<li>Add Tornado module to your django setup. If you use buildout, add Tornado git checkout to buildout.cfg using <em>minitage.recipe.fetch</em> recipe, like this:
<pre lang="ini">[buildout]
...
parts =
...
    tornado
    django
...

[tornado]
recipe = minitage.recipe.fetch
urls = git://github.com/facebook/tornado.git | git | | ${buildout:parts-directory}/tornado

[django]
recipe = minitage.recipe.scripts
initialization =
    import os
    os.environ['DJANGO_SETTINGS_MODULE']='project.settings.development'
scripts =
    django
eggs =
    Django
    ...
entry-points=
    django=django.core.management:execute_from_command_line
extra-paths =
    ${buildout:directory}
    ${tornado:location}
...</pre>
</li>
<li>Next, create a command-line extension hierarchy in your project&#8217;s main app:
<pre>$ mkdir project/myapp/management
$ touch project/myapp/management/__init__.py
$ mkdir project/myapp/management/commands
$ touch project/myapp/management/commands/__init__.py</pre>
</li>
<li>Last, add a runtornado.py script in project/myapp/management/commands/ folder with the following content:
<pre lang="python">from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
import os
import sys

class Command(BaseCommand):
    option_list = BaseCommand.option_list + ()
    help = "Starts a Tornado Web."
    args = '[optional port number, or ipaddr:port]'

    def handle(self, addrport='', *args, **options):
        import django
        from django.core.handlers.wsgi import WSGIHandler
        from tornado import httpserver, wsgi, ioloop

	sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
	sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)

        if args:
            raise CommandError('Usage is runserver %s' % self.args)
        if not addrport:
            addr = ''
            port = '8000'
        else:
            try:
                addr, port = addrport.split(':')
            except ValueError:
                addr, port = '', addrport
        if not addr:
            addr = '127.0.0.1'

        if not port.isdigit():
            raise CommandError("%r is not a valid port number." % port)

        quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'

        def inner_run():
            from django.conf import settings
            print "Validating models..."
            self.validate(display_num_errors=True)
            print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE)
            print "Server is running at http://%s:%s/" % (addr, port)
            print "Quit the server with %s." % quit_command
            application = WSGIHandler()
            container = wsgi.WSGIContainer(application)
            http_server = httpserver.HTTPServer(container)
            http_server.listen(int(port), address=addr)
            ioloop.IOLoop.instance().start()

        inner_run()</pre>
</li>
</ol>
<p>To run your tornado webserver, you just need to call your usual management program like manage.py with runtornado command, with the same syntax as runserver. In my case, I just run production server using <a rel="nofollow" href="http://supervisord.org/">supervisord</a>, with a command like this:</p>
<pre>$ ./bin/django runtornado --settings=project.settings.production 8000</pre>
<p>If you found this quick how-to useful, remember to follow me on <a rel="nofollow" href="http://twitter.com/geekscrap">Twitter</a> or subscribe to my feed for more django tips.</p>
]]></content:encoded>
			<wfw:commentRss>http://geekscrap.com/2010/02/integrate-tornado-in-django/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
