20 ms·
Tornado: FriendFeed's non-blocking Python web server is now open source
- casey 17y agoAn instance of the chat demo is running here: http://chan.friendfeed.com:8888/ http://chan.friendfeed.com:8888/ Website: http://www.tornadoweb.org/ http://www.tornadoweb.org/ Source: http://github.com/facebook/tornado/tree/master http://github.com/facebook/tornado/tree/master
- far33d 17y agoThe chat demo seems to have turned into a tech discussion about the framework. Love it.
- charlesju 17y agoIs this similar to EventMachine in Ruby?
- fizx 17y agoEM is a general-purpose library for nonblocking IO. Tornado is an HTTP server. In as much as they're both about nonblocking IO, they are similar.
- ddispaltro 17y agoTornado has its own EventMachine-like equivalent as part of the stack they released. So you could use it to do TCP non-blocking IO if I grokked the code correctly.
- superjared 17y agoI'd say it's a little more similar to Thin, which is a web server based on EM.
- xal 17y agoPort: http://gist.github.com/184760 http://gist.github.com/184760
- dlsspy 17y agoI could use this in apps today if it used twisted instead of reinventing it.
- finiteloop 17y agoHow many deployed web apps really use Twisted? There are like 3 web packages in Twisted, most of which are really buggy, and as far as I could tell, barely used (even they acknowledge this, see http://twistedmatrix.com/trac/wiki/WebDevelopmentWithTwisted http://twistedmatrix.com/trac/wiki/WebDevelopmentWithTwisted). When we were developing this, we found that Twisted introduced as many problems as it solved in terms of incomplete features and bugs. The other protocols seem to have more attention than HTTP from what I could tell.
- abstractbill 17y agoThe other protocols seem to have more attention than HTTP from what I could tell. I'm not sure even that is true. When I used twisted to write the justin.tv chat server (which is essentially an irc server) I gave up on twisted's irc protocol implementation and wound up just using twisted as an I/O layer.
- finiteloop 17y agoYah, that seems to be Twisted's problem. I think projects that don't have a real site using them day-to-day end up in this state often - lots of incomplete implementations of lots of features.
- dlsspy 17y ago"How many deployed web apps really use Twisted?" This is sort of the point. twisted isn't a web framework. It's a networking framework. I work on a lot of really awesome networking projects that either don't have web interfaces (various xmpp services) or have ones that need work (buildbot). Instead of filling an obviously missing hole in an existing framework, a new one was created that is missing all of the stuff that the other project has. The twisted http client stuff is quite good. I used it along with a friend to build a tool that is a realtime (in the web sense) gateway between friendfeed and xmpp clients a couple days after the realtime API was released (before friendfeed launched their own). It works very well and I still use it today. Unfortunately, if I wanted to build a tool that did similar stuff with a Tornado front-end, I'd have to write a new HTTP client that's compatible with Tornado's event loop (unless I'm mistaken). Everything comes at a cost. Tornado demonstrably solved Friendfeed's problems quite well, but, as I stated above, I can't use it to solve my problems because even if I rewrote my apps, I'd lose all of the rest of twisted upon which I'm relying. e.g. I can't just bolt it onto buildbot (which would be so ideal as our web interface is suffering from lack of a framwork, but the backend is really good).
- tdavis 17y agoThis is more of a combination of a web server and a web framework, which is what I find fascinating about it. Twisted has had a web server forever, but despite a significant amount of experience in Twisted Land, I'd never write a full app using it! Add to that the (apparently) standalone low-level modules and we've got some seriously awesome tech that FriendFeed/Facebook have supplied for free. Thanks a lot, fellas. Asynchronous networking programming in Python is somewhat of a bear so it's really nice to see a tool get released that improves it!
- auston 17y agoAt a first glance, this looks SERIOUSLY awesome!
- omouse 17y agoDoes this implement all of the HTTP 1.0 and 1.1 protocol specs? I'm kinda confused by the code :S
- finiteloop 17y agoIt implements a lot of HTTP/1.1, but see http://www.tornadoweb.org/documentation#caveats-and-support http://www.tornadoweb.org/documentation#caveats-and-support. In practice, we run behind an nginx reverse proxy, so we assume there are missing areas. We recommend people run in a similar fashion in production. We did not optimize for protocol completeness given our production setup.
- deleted 17y ago[deleted]
- drawkbox 17y agoThis is great for python, a proven web framework that was stressed on friend feed. Thanks ff team! I have been torn on my next python server project between web2py, cherrypy and django and I think I just decided.
- n8agrin 17y agoAwesome to see more Python webservers coming to light, and fast ones at that. One observation though; anyone else notice that the bar chart is a bit misleading? It compares running Tornado in 4 processes behind nginx to running Django behind Apache and Cherrypy as a single Python process. As a fellow coworker put it, "With 4 extra processes running of course it will be 4 times as fast." I'm not opposed to this kind of comparison when the intent is to show how configurations can increase req/sec, but if the intent is to compare one Pythonic webserver to another, this comparison seems a bit unfair. That said, assuming the "Tornado (1 single-threaded frontend)" measure is simply Tornado running as a single Python process, it still is plenty faster than Cherrypy.
- finiteloop 17y agoCherryPy is multi-threaded, so I am not sure what you are saying is correct. There are two types of servers: multi-threaded, multi-process. Tornado is multi-process. If your server is multi-threaded, it uses all of the cores without additional processes. CherryPy did max out the CPU on all of the cores in the load test, so I think it was a fair test.
- deleted 17y ago[deleted]
- dowskitest 17y agoIf you ran a single CherryPy instance, I don't see how that is possible. The Python global interpreter lock prevents a single process from making use of multiple cores.
- jnoller 17y agoNo, it doesn't. I/O bound tasks can heavily use multiple cores just fine using threads.
- TimothyFitz 17y agoIf you're CPU bound in pure-python computations then the GIL (Global Interpreter Lock) will cause you to only make use of one core. This is intentional: threads are hard, processes are simple.
- polvi 17y agoThis is great. Any idea if they will do the same for the FriendFeed datastore?
- calaniz 17y agoThis looks great. I'm likely to look at it a little more in the future. I've been using Second Life's asyncrounous coroutine library called eventlet. I've implemented most of my code with a good lightweight framework that fits; restish. On top of that, I use spawning to manage my server processes. I myself have seen these kinds of numbers with my own app tests.
- xal 17y agoI implemented the same idea in Ruby event machine: http://gist.github.com/184760 http://gist.github.com/184760 Obviously missing features (auth, nicks, scrolling) but that can all be added in a few mins.
- tiredandempty 17y agohow about turning this to a full framework? or is there one already?
- xal 17y agoI'll brainstorm the idea. I have some ideas of how to turn this evented programming into a very natural flow using ruby 1.9.1's fibers.
- poutine 17y agoThis would be extremely interesting as this area is one major weakpoint for available Ruby frameworks.
- extension 17y agoI've been tinkering with continuation passing web frameworks in Ruby, but haven't had time to really dive into making one. There is plenty of inspirational material out there e.g. Seaside. If you get anywhere, myself and probably others in the community would be interested to hear about it. http://blog.extension.ws/11/modal_web_experiments http://blog.extension.ws/11/modal_web_experiments
- prakash 17y agoBret, quick question. Does the framework support an esi type tags to abstract out personalized info? thanks!
- finiteloop 17y agoI am not sure what esi type tags are. Mind sending me a link? Suffices to say, no, we do not support that :)
- SwellJoe 17y agoEdge Side Includes. Proxies like Squid and Varnish support it for inclusion of dynamic data in otherwise cache-able pages. http://www.w3.org/TR/esi-lang http://www.w3.org/TR/esi-lang It seems like this would not be mandatory in Tornado, since it is an app server; from my reading I'm assuming all pages are dynamic.
- prakash 17y ago:-) ESI: http://www.akamai.com/html/support/esi.html http://www.akamai.com/html/support/esi.html e.g. When you and I log into ff, simplifying greatly, that page would say, "Welcome, Bret" or "Welcome, Prakash". If you could abstract away "Bret" and "Prakash", that page would be cacheable. And, the db hit is only for that particular fragment. You would need to re-code the pages with esi tags to do it. The other way would be to use javascript to do the same. What do you think?
- mapleoin 17y agoWho wants a (unofficial for now) Fedora rpm ? [0] I just hacked this together in half an hour. Time to sleep now. [0] http://mapleoin.fedorapeople.org/pkgs/tornado/tornado-0.1-1.fc11.noarch.rpm http://mapleoin.fedorapeople.org/pkgs/tornado/tornado-0.1-1....
- usaar333 17y agoWhat exactly does 'non-blocking' mean in the context of a webserver?
- cheriot 17y agoHolding the TCP connection open does not tie up all the resources of the request handling thread. That way a large number of inactive connections can stay open.
- usaar333 17y agoThanks. So to clarify, this is just the same as what lighttpd phrases as a 'select()-/poll()-/epoll() based web server'? It seems that the main advantage of this is that you have one thread manging many sockets. I am a bit surprised that blocking kthreads would be so much slower relatively. What causes the slowness? Context switching? Additional stack memory usage?
- kingkongrevenge 17y agoI don't think threads are slower or less scalable anymore. The OS threading systems have improved a lot over the last four years.
- Tichy 17y agoAt least if you use a language like Erlang, I suppose. (Although I think that wouldn't be OS threading, but still).
- extension 17y agoErlang threads (processes actually), are very different from OS threads. They are extremely lightweight and allow you to do this kind of event driven networking with threaded code.
- agazso 17y agoYou guessed right. Context switching is expensive, and the default stack size default is in the megabyte range. So if you want to have 10K connections open, it takes about 10GB memory. You can of course shrink the stack size, but you have to measure your programs stack usage before doing that and it is quite cumbersome. With an event driven architecture you only have to hold the session information per connection in memory which can be as low as 4K, therefore you are able to maintain (depending on the complexity of the protocoll) n*100K connections. The only drawback that you have to write and think your whole program event driven; you write callbacks for each io and timer operation and the control flow won't be clear if you read the program.
- cheriot 17y agoDefinitely rough around the edges, but looks like a great foundation. A few notes: - template.py: "Error-reporting is currently... uh, interesting." - url mapping looks primitive - no form helpers - database.py looks decent, but is mysql only - Very nice to see the security considerations in signed cookies, auth, csrf protection. Overall, it looks like they've done the trickier parts of building a web framework and left it to the user/community to add the parts web developers use most frequently (form & url helpers, code organization, and orm). I love Facebook's enlightened approach to open source. If only one of their open source projects takes off, it will benefit them tremendously.
- ComputerGuru 17y agoI've been looking for a good framework to begin serious web development on for someone coming from a decade-long career in desktop development (see the discussion at http://news.ycombinator.com/item?id=808191 http://news.ycombinator.com/item?id=808191), and decided this release co-incides nicely with my newly-started quest and gave it a shot. I realize Tornado isn't any different from the other Python frameworks with regards to coding style, etc. but the the fact that this framework comes complete with a web server means I don't have to worry about that part of the equation making developing Python-based webapps almost identical to developing a C++ library with one of the many HTML-based UI frontends :) Having a great time playing around with it... almost done with a basic forum system built on Tornado + Storm (https://storm.canonical.com/ https://storm.canonical.com/).. I think I'm getting the hang of this whole web-development thing! :D
- apoirier 17y agoFor a real different coding style, more like a desktop development, take a look at Nagare (http://www.nagare.org http://www.nagare.org), a continuation and components based web framework. And it also comes with an integrated HTTP server (and a fastCGI one) ;)
- RoboTeddy 17y agoIt seems like blocking calls to data sources (the database, memcache, etc) would screw with a lot of the benefits of running the framework asynchronously. If your Tornado processes freeze while making synchronous backend requests, you're gonna need a lot of them, which probably kills a lot of the value. Now all we need are async data clients that tie into the Tornado event loop, and a clean way to yield control back and forth (perhaps with coroutines - http://www.python.org/dev/peps/pep-0342/ http://www.python.org/dev/peps/pep-0342/). Unfortunately, I don't think there are any async Python mysql clients (PHP has one now - http://www.scribd.com/doc/7588165/mysqlnd-Asynchronous-Queries-and-more http://www.scribd.com/doc/7588165/mysqlnd-Asynchronous-Queri...) A web app written like that would run like it's on fire. The event loop would just roll through everything asynchronously. You could even automatically batch together data calls across http requests to make things easier on the data tier.
- DenisM 17y agoThe browser-webserver delay resulting from long polling is much larger the frontend-backend delay. I think there is at least an order of magnitude difference there, hence an order of magnitude reduction is the amount of idle state kept on the server.
- RoboTeddy 17y agoYeah, I agree. For long-polling apps it seems like Tornado gives you a huge advantage. For other web apps though, the frontend-backend delay is comparatively more important, because usually there's a load balancer or reverse proxy in charge of buffering up data arriving from distant/laggy browser connections and hitting the web application server with it all at once.
- extension 17y agoIf you go with an evented architecture like this, you have to use it for pretty much all I/O or the whole thing falls apart. Lack of drivers and protocols has been a large barrier to adoption.
- n8agrin 17y agoThe templating system they developed looks pretty sweet http://github.com/facebook/tornado/blob/master/tornado/template.py http://github.com/facebook/tornado/blob/master/tornado/templ.... Just played around with it a bit and it's basically what I want: 1) Simple and clear syntax (e.g. they use 'end' not endfor, endblock, etc) 2) Assign template variables to anything (including functions) 3) Don't over-restrict the author (e.g. they allow list comprehensions in if tags) 4) Block and extends statements. Error handling seems to be a little clearer than other template languages though still not great: http://gist.github.com/184934 http://gist.github.com/184934 Clearly it's not going to be for everyone but after slogging around with Mako for the last year (<%namespace:def /> tags anyone?) this is like a breath of fresh air.
- finiteloop 17y agoThanks! Yah, the reason we rolled our own is because all the rest were so restrictive to authors. We didn't want a template system telling us what we should and shouldn't do in templates, so ours was a very thin layer on top of what basically translates directly to Python. It is actually one of my favorite parts of the system.
- statictype 17y agoWhat would be the advantage of using this over, say, lighttpd with one of the many existing python frameworks? Does this web server offer any specific gains? Or is it just a question of personal taste?