Tornado 2.1 released
tornadoweb.org
tornadoweb.org
- They created a lot of Web-stuff parsing code themselves, when Werkzeug provides a tested and thorough implementation of a lot of that. (Especially routing, regex-based routing just looks horribly kludgy once you have used werkzeug.routing.)
- They created their own template language when they could have used Jinja. (In fact, tornado.template is basically a half-as-powerful copy of Jinja.)
- They created their own database access layer when they could have used SQLAlchemy instead.
Sometimes I think people take the concept of "minimal dependencies" way too far.
It is simple enough, the code is clear and small enough to dive into if you have any problems, and it works just great.
Some personal experiences: With Django, I specifically don't like ORM and it's template language. Also, I thought the admin interface would reduce the need to write input UIs, but at the end of the day, it's not that suitable for end-user when you have several end-user roles with different access right patterns.
If you (read: I) are going to replace Django's template language and leave out ORM and admin interface out of Django, Django doesn't really shine anymore and simpler frameworks like Tornado provide cleaner base for your development.
Does anyone have experience with using this ?
Also, what do people use for form validation with Tornado ?
The main advantage of async is not blocking if you call an external web API.
Imagine an app that receives an HTTP request every second. One in five of these requests requires making a query that takes 3 seconds to complete. The rest is serviced immediately. You don't want the long request freezing your entire server and preventing the fast requests from being serviced.
We experimented with different async DB approaches, but settled on
synchronous at FriendFeed because generally if our DB queries were
backlogging our requests, our backends couldn't scale to the load
anyway. Things that were slow enough were abstracted to separate
backend services which we fetched asynchronously via the async HTTP
module.
I may open source the async MySQL client I wrote, but I am still
skeptical of the long term value given the code complexity it
introduces.
BretDisclaimer: I wrote an async DB module for Twisted/PostgreSQL and it did not turn out to be all that complex.
Also, Tornado is now introducing some kind of interface to Twisted's event loop, which does have everything ported.
Bret just doesn't seem to want async My-SQL in the main code base.
Personally I would go with async DB, or have DB access in its own thread(s) and async communicate with that.
I figure after the first million users, your embarrassingly parellel app server layer is not your bottleneck, it's getting the database to scale.
* it feels easier to scale up than Flask, but that could be my minimal Flask experience showing. Certainly, it is more performant than basic Flask installations and configurations.
* it makes it harder to separate your concerns than, say, Django. I've been working in Django for a long time, and while I have definite issues with the "app"-style packaging (ie. if I add an external forum framework, for instance, I need to munge my "profiles" app to support it), it does feel easier to separate your concerns in Django than in most other frameworks I've used.
* it's fast, and reasonably agnostic - the MySQL DB layer, for instance, can be completely eschewed for something else.
I imagine they've added a lot to it since then, and the service itself isn't something I've looked at for a while (failed startup idea). But from what I used back then, I'd definitely recommend it.
www.site.com/controller/action/params/?vars -> would route to ->
class controller(requestHandler):
def get_action(self, *params, **vars):
#do something
self.write(response)
def post_action2(self, *params, **vars):
#.... and so on .... class LoginHandler(RequestHandler):
def get(self):
self.render('login.html')
def post(self):
self.set_secure_cookie(self.get_argument('username'))
self.redirect('/')
Having one class per URL is very common and perhaps it's more than a decade of Python web programming but I like that. Makes for neat code.That would get really messy in a controller-with-multiple-actions pattern as the controller classe now has a lot more methods in a single class: all the HTTP methods it handles plus the callbacks for all of them.
Having controller per one action would put overhead on the code lines you write.
I know Python but never played with server-side javascript before.
Whichever you choose, you may find that http://socket.io/ saves you some time by inventing various wheels you may have needed to reinvent (for use with tornado, see the tornadio project).