Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Développement web asynchrone avec Tornado

Ronan Amicel
September 15, 2012

Développement web asynchrone avec Tornado

Ronan Amicel

September 15, 2012
Tweet

More Decks by Ronan Amicel

Other Decks in Programming

Transcript

  1. Tornado c’est quoi ? • Un serveur web – scalable

    et non-bloquant (utilise epoll ou kqueue) • Un framework web – proche de web.py ou webapp – exploite l’infrastructure non-bloquante sous-jacente
  2. Bonjour les gens ! import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler):

    def get(self): self.write("Bonjour les gens !") application = tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
  3. (Some) Batteries Included • Moteur de templates • Localisation •

    Client HTTP asynchrone • Client MySQL asynchrone • OpenID et OAuth (Twitter, Facebook, Google) • Web Socket
  4. Cas d'utilisation • Seul ou en complément d'un framework «

    classique » • Sites à forte charge (milliers de requêtes / seconde) • Messagerie instantanée, chat rooms • Requêtes dépendant de services externes à latence variable (API Facebook, Twitter, etc.) • Mises à jour « temps réel » dans une page web
  5. Mises à jour « temps réel » Polling (Ajax) Long

    Polling (Comet) Streaming (Web Socket) Navigateur Serveur Navigateur Serveur Navigateur Serveur événements événements événements
  6. Web Socket (côté serveur) from tornado.websocket import WebSocketHandler class EchoWebSocket(WebSocketHandler):

    def open(self): print "WebSocket opened" def on_message(self, message): self.write_message(u"You said: " + message) def on_close(self): print "WebSocket closed"
  7. Web Socket (côté client) var ws = new WebSocket("ws://localhost:8888/websocket"); ws.onopen

    = function () { ws.send("Hello, world"); }; ws.onmessage = function (evt) { alert(evt.data); };
  8. Requêtes asynchrones from tornado.httpclient import AsyncHTTPClient from tornado.web import RequestHandler,

    asynchronous class MyRequestHandler(RequestHandler): @asynchronous def get(self): http = AsyncHTTPClient() http.fetch('http://friendfeed.com/', self._on_download) def _on_download(self, response): self.write('Downloaded!') self.finish()
  9. Masquer les callbacks avec tornado.gen from tornado.gen import engine, Task

    from tornado.httpclient import AsyncHTTPClient from tornado.web import RequestHandler, asynchronous class MyRequestHandler(RequestHandler): @asynchronous @engine def get(self): http = AsyncHTTPClient() response = yield Task(http.fetch, 'http://friendfeed.com/') self.write('Downloaded!') self.finish()
  10. Tâches concurrentes avec tornado.gen class MyRequestHandler(RequestHandler): @asynchronous @engine def get(self):

    http = AsyncHTTPClient() response1, response2 = yield [ Task(http.fetch, url1), Task(http.fetch, url2), ] self.write('Downloaded!') self.finish()
  11. Historique • 2007 : FriendFeed • Août 2009 : rachat

    par Facebook • Septembre 2009 : première version diffusée sous licence Apache 2.0 • Juillet 2010 : Tornado 1.0 • Juin 2011 : Tornado 2.0 • Septembre 2012 : Tornado 2.4
  12. Les côtés négatifs • Asynchrone – Moins lisible que du

    code synchrone – Plus complexe à déboguer • Communauté – Moins populaire que Django, Flask, Pyramid...