Tornado<br />Rocking the Non-Blocking Web<br />Contact:<br />Twitter:	<br />Kurtiss Hare, CTO & Co-Founder of playhaven.co...
What is Tornado?<br />Scalable, Non-blocking Web Server<br />Powered www.friendfeed.com<br />Now open-sourced by Facebook ...
Why Tornado?<br />
Why Tornado?<br />Paul Buchheit<br />
Why Tornado?<br />Don’t<br />Be<br />Paul Buchheit<br />
Why Tornado?<br />Processor/Thread Model<br />CherryPy, Mod_WSGI, uWSGI, …<br />Lightweight Threads<br />Gevent, Eventlet,...
Why Tornado?<br />Trying to address the c10k problem?<br />10,000 concurrent connections<br />Processor/thread is known to...
Tornado’s Architecture<br />~2000 clients<br />tornado.ioloop._poll<br />tornado.web.RequestHandler<br />tornado.httpserve...
Tornado’s Architecture<br />tornado.ioloop._poll<br />Edge-triggered when possible (epoll/kqueue)<br />Falls back on level...
Hello, world<br />import tornado.httpserver<br />import tornado.ioloop<br />import tornado.web<br />class MainHandler(torn...
Rocking the Non-Block<br />class MainHandler(tornado.web.RequestHandler):<br />    @tornado.web.asynchronous<br />    def ...
Performance Notes<br />Source: http://developers.facebook.com/blog/post/301<br />
Performance Notes<br />Better Comparisons<br />Node.js – Tornado by 110% throughput [0]<br />Twisted.Web – Tornado by 84% ...
Let’s Code<br />
Questions? Beer?<br />
Upcoming SlideShare
Loading in...5
×

Tornado web

6,987

Published on

Rocking the Non-blocking Web

Published in: Technology
0 Comments
20 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,987
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
132
Comments
0
Likes
20
Embeds 0
No embeds

No notes for slide

Tornado web

  1. 1. Tornado<br />Rocking the Non-Blocking Web<br />Contact:<br />Twitter: <br />Kurtiss Hare, CTO & Co-Founder of playhaven.com<br />@kurtiss<br />
  2. 2. What is Tornado?<br />Scalable, Non-blocking Web Server<br />Powered www.friendfeed.com<br />Now open-sourced by Facebook after FF acquisition<br />
  3. 3. Why Tornado?<br />
  4. 4. Why Tornado?<br />Paul Buchheit<br />
  5. 5. Why Tornado?<br />Don’t<br />Be<br />Paul Buchheit<br />
  6. 6. Why Tornado?<br />Processor/Thread Model<br />CherryPy, Mod_WSGI, uWSGI, …<br />Lightweight Threads<br />Gevent, Eventlet, …<br />IOLoop/Callback Model<br />Tornado, Cogen, …<br />What are you trying to do?<br />
  7. 7. Why Tornado?<br />Trying to address the c10k problem?<br />10,000 concurrent connections<br />Processor/thread is known to fall over<br />Trying to enable real-time/long-polling, WebSockets?<br />Different problem than handling many short-lived, pipelined requests.<br />Want to extend your arsenal with a tool that addresses these problems?<br />Tornado might be for you.<br />
  8. 8. Tornado’s Architecture<br />~2000 clients<br />tornado.ioloop._poll<br />tornado.web.RequestHandler<br />tornado.httpserver.HTTPServer<br />socket.socket<br />tornado.ioloop.IOStream<br />tornado.httpserver.HTTPConnection<br />tornado.web.Application<br />Routing/MVC<br />tornado.ioloop<br />
  9. 9. Tornado’s Architecture<br />tornado.ioloop._poll<br />Edge-triggered when possible (epoll/kqueue)<br />Falls back on level triggered (select)<br />Handles:<br />Callback registration<br />New connections<br />Connections with new data<br />Heart of Tornado’s approach to c10k<br />
  10. 10. Hello, world<br />import tornado.httpserver<br />import tornado.ioloop<br />import tornado.web<br />class MainHandler(tornado.web.RequestHandler):<br /> def get(self):<br /> self.write("Hello, world")<br />application = tornado.web.Application([<br /> (r"/", MainHandler),<br />])<br />if __name__ == "__main__”:<br /> http_server = tornado.httpserver.HTTPServer(application)<br /> http_server.listen(8888)<br /> tornado.ioloop.IOLoop.instance().start()<br />
  11. 11. Rocking the Non-Block<br />class MainHandler(tornado.web.RequestHandler):<br /> @tornado.web.asynchronous<br /> def get(self):<br /> http = tornado.httpclient.AsyncHTTPClient()<br /> http.fetch("http://friendfeed-api.com/v2/feed/kurtiss",<br /> callback=self.async_callback(self.on_response))<br /> def on_response(self, response):<br /> if response.error: raise tornado.web.HTTPError(500)<br /> json = tornado.escape.json_decode(response.body)<br /> self.write("Fetched " + str(len(json["entries"])) + " entries ”)<br /> self.finish()<br />
  12. 12. Performance Notes<br />Source: http://developers.facebook.com/blog/post/301<br />
  13. 13. Performance Notes<br />Better Comparisons<br />Node.js – Tornado by 110% throughput [0]<br />Twisted.Web – Tornado by 84% shorter average response time [1]<br />Caveat Emptor, OK?<br />http://nichol.as/benchmark-of-python-web-servers<br />Of note, “Server Latency,” vs. gEvent, uWSGI<br />Likely due to CPU availability<br />Nothing beats a load test on your own environment<br />PlayHaven’s use is modest, but growing:<br /><500 concurrent web requests<br />No long polling … yet.<br />[0] http://news.ycombinator.com/item?id=1089340<br />[1] http://www.apparatusproject.org/blog/2009/09/twisted-web-vs-tornado-part-deux/<br />
  14. 14. Let’s Code<br />
  15. 15. Questions? Beer?<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×