36
different Web programming Dima Malenko for Ruby Meetup

Tornado - different Web programming

Embed Size (px)

DESCRIPTION

Slides from talk about Tornado Web framework for Dnipro Ruby community

Citation preview

Page 1: Tornado - different Web programming

– different Web programming

Dima Malenko

for Ruby Meetup

Page 2: Tornado - different Web programming

2002

C++Win32MFCCORBA

Page 3: Tornado - different Web programming

ASP.NET Web Forms

public class FirstPage: System.Web.UI.Page{ public System.Web.UI.WebControls.Label lblMessage;

private int i = 0;

protected void Page_Load(object sender, EventArgs e) { i = i + 1; lblMessage.Text = i.ToString(); }}

Page 4: Tornado - different Web programming

Web Programming Model

Client Server

Request with parameters

HTML response

Page 5: Tornado - different Web programming

MVCBest forW

eb

Page 6: Tornado - different Web programming

How Web Server Works?

• Create socket• Bind socket• Listen on socket

• Accept new connection from a client• Receive data from the client• Process the request somehow• Send response to the client

• Wait for a new connection

Page 7: Tornado - different Web programming

How Web Server Works?

• Create socket• Bind socket• Listen on socket

• Accept new connection from a client• Receive data from the client• Process the request somehow• Send response to the client

• Wait for a new connection

Sep

ara

te t

hre

ad

Page 8: Tornado - different Web programming

Why the “separate thread”?

Page 9: Tornado - different Web programming

How Web Server Works?

• Create socket• Bind socket• Listen on socket

• Accept new connection from a client• Receive data from the client• Process the request somehow• Send response to the client

• Wait for a new connection

Sep

ara

te t

hre

ad

Page 10: Tornado - different Web programming
Page 11: Tornado - different Web programming

Threads cost

• Memory overhead– Default thread stack size in Linux – 8M

• Context switches cost– It takes ~2-3µs to switch context in

Linux– http://blog.tsunanet.net/2010/11/how-

long-does-it-take-to-make-context.html

Page 12: Tornado - different Web programming
Page 13: Tornado - different Web programming

C10k problem

http://www.kegel.com/c10k.html

Page 14: Tornado - different Web programming

Non-blocking I/O!

Page 15: Tornado - different Web programming

What would you put in front of loaded Web site?

Page 16: Tornado - different Web programming
Page 17: Tornado - different Web programming

Why Nginx?

Page 18: Tornado - different Web programming

Ability to handle more than 10,000 simultaneous connections with a low memory footprint (~2.5 MB per 10k inactive HTTP keep-alive connections)

“Wikipedia

Page 19: Tornado - different Web programming

How is that possible?

• Non-blocking networking using fastest interface on any given platform– kqueue (FreeBSD 4.1+)– epoll (Linux 2.6+)– rt signals (Linux 2.2.19+)– /dev/poll (Solaris 7 11/99+)– event ports (Solaris 10)– select– poll

Page 20: Tornado - different Web programming

• Python web framework and async networking library

• Originally developed for FriendFeed• Ideal for long polling, WebSockets

and long-lived connections

www.tornadoweb.com

Page 21: Tornado - different Web programming
Page 22: Tornado - different Web programming
Page 23: Tornado - different Web programming

import tornado.ioloopimport tornado.web

class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world")

application = tornado.web.Application([ (r"/", MainHandler),])

if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()

Page 24: Tornado - different Web programming

Handling Requests

class ProductHandler(tornado.web.RequestHandler): def get(self, product_id): self.write("Information about " + product_id)

@tornado.web.authenticated def post(self, product_id): # store updated product info

application = tornado.web.Application([ (r"/product/([0-9]+)", ProductHandler)])

Page 25: Tornado - different Web programming

Templates<html> <head> <title>{{ title }}</title> </head> <body> <ul> {% for item in items %} <li>{{ escape(item) }}</li> {% end %} </ul> </body> </html>

class MainHandler(tornado.web.RequestHandler): def get(self): items = ["Item 1", "Item 2", "Item 3"] self.render("template.html", title="My title", items=items)

Page 26: Tornado - different Web programming

And That’s It?

Page 27: Tornado - different Web programming

Web SiteShow list of

currently running apps with their

titles

NodeRuns many real-time applications

AppChanges titles

whenever it wants

Page 28: Tornado - different Web programming

Web SiteShow list of

currently running apps with their

titles

NodeRuns many real-time applications

AppChanges titles

whenever it wants

How would you make sure user can see updated titles on the web?

Page 29: Tornado - different Web programming

Web SiteShow list of

currently running apps with their

titles

NodeRuns many real-time applications

AppChanges titles

whenever it wants

What if…

300-400ms

AppChanges titles whenever it

wants

AppChanges titles

whenever it wants

AppChanges titles

whenever it wants

AppChanges titles

whenever it wants

AppChanges titles

whenever it wants

Page 30: Tornado - different Web programming

Non-blocking Requests

class AppUpdatesHandler(tornado.web.RequestHandler): @tornado.web.asynchronous def get(self): http = tornado.httpclient.AsyncHTTPClient() request = tornado.httpclient.HTTPRequest( "http://www.frontend.com", method="POST", ...) http.fetch(request, callback=self.on_response) self.finish()

def on_response(self, response): if not response.error: log.debug("Title updated”)

Page 31: Tornado - different Web programming

WebSockets

class WebSocket(websocket.WebSocketHandler): def open(self): print "WebSocket opened"

def on_message(self, message): print "Message: " + message

def on_close(self): print "WebSocket closed"

Page 32: Tornado - different Web programming

How is it possible?

Cooperative Multitasking

Page 33: Tornado - different Web programming

How does it work?

• Event loop– Tornado.ioloop.IOLoop– Level-triggered, uses epoll on Linux and

kqueue on BSD

• Futures– Result of an async operation

Page 34: Tornado - different Web programming

Coroutines

class AppUpdatesHandler(tornado.web.RequestHandler): @tornado.web.asynchronous @tornado.gen.coroutine def get(self): http = tornado.httpclient.AsyncHTTPClient() request = tornado.httpclient.HTTPRequest( "http://www.frontend.com", method="POST", ...) self.finish() response = yield http.fetch(request) if not response.error: log.debug("Title updated”)

Page 35: Tornado - different Web programming

Conclusions

• Web has changed, so programmers should too

• You want to face C10k problem• There means to solve it• Learn to think asynchronously• Check out www.tornadoweb.org

Page 36: Tornado - different Web programming

Questions?

[email protected]

@dmalenko