30
What Is Async, How Does It Work, A. Jesse Jiryu Davis @jessejiryudavis MongoDB When Should I Use It? &

What Is Async, How Does It Work, And When Should I Use It?

Embed Size (px)

DESCRIPTION

Python’s asynchronous frameworks, like asyncio, Tornado, and Twisted, are increasingly important for writing high-performance web applications. Even if you’re an experienced web programmer, you may lack a rigorous understanding of how these frameworks work and when to use them. Let’s see how asyncio's event loop works, and learn how to efficiently handle very large numbers of concurrent connections.

Citation preview

Page 1: What Is Async, How Does It Work, And When Should I Use It?

What Is Async, How Does It Work,

A. Jesse Jiryu Davis

@jessejiryudavis

MongoDB

When Should I Use It?&

Page 2: What Is Async, How Does It Work, And When Should I Use It?

Food in NYC

• Subs

• Pizza

• Omakase

Page 3: What Is Async, How Does It Work, And When Should I Use It?

Subs

Counter

⚇!client

⚇!sandwich!maker

pool☺

Page 4: What Is Async, How Does It Work, And When Should I Use It?

CPU-bound web app

Client ServerClients

• Throughput bound by computation• No async

Page 5: What Is Async, How Does It Work, And When Should I Use It?

Pizza

5

Counter

⚇!client

⚇!pizza cook

oven🍕

⚇⚇⚇

Page 6: What Is Async, How Does It Work, And When Should I Use It?

Normal web app

Client Server

• Throughput bound by memory • Async

Backend Database,

OAuth service, etc.

Clients

Page 7: What Is Async, How Does It Work, And When Should I Use It?

Omakase

7

Counter

⚇!waiter

kitchen

⚇⚇⚇!clients

Page 8: What Is Async, How Does It Work, And When Should I Use It?

Websocket application

Client Serversockets

EventssocketsClients

• Number of clients bound by memory • Async

Page 9: What Is Async, How Does It Work, And When Should I Use It?

What’s async for?

Minimizes resources per connection.

Page 10: What Is Async, How Does It Work, And When Should I Use It?

C10K

kegel.com/c10k.html

Page 11: What Is Async, How Does It Work, And When Should I Use It?

Why is async hard to code?BackendClient Server

request

response

store state

request

response

time

Page 12: What Is Async, How Does It Work, And When Should I Use It?

Why is async hard to code?BackendClient Server

websocket

event

store state

register for events

event

time

Page 13: What Is Async, How Does It Work, And When Should I Use It?

Ways to store state:

Coding difficulty

Threads

Callbacks

Mem

ory

per

co

nn

ectio

n

Page 14: What Is Async, How Does It Work, And When Should I Use It?

Ways to store state:

• Threads • Callbacks !

... and: !

• Coroutines • Greenlets !

and so on....

Page 15: What Is Async, How Does It Work, And When Should I Use It?

So, what is async?

• Single-threaded • I/O concurrency • Non-blocking sockets • epoll / kqueue • Event loop

Page 16: What Is Async, How Does It Work, And When Should I Use It?

asyncio

• AKA “Tulip” • Python 3.4 standard library • Implements PEP 3156 • Standard event loop • Coroutines

Page 17: What Is Async, How Does It Work, And When Should I Use It?

17

Page 18: What Is Async, How Does It Work, And When Should I Use It?

Layers

18

Application

Protocol

Transport

Event Loop

Selectors

asyncio{autobahn websockets

example.py

Page 19: What Is Async, How Does It Work, And When Should I Use It?

from autobahn import (WebSocketServerProtocol,! WebSocketServerFactory)!

example.py

Page 20: What Is Async, How Does It Work, And When Should I Use It?

clients = set()!!class ChatProtocol(WebSocketServerProtocol):! def onConnect(self):! clients.add(self)!! def onMessage(self, msg):! for c in clients:! if c is not self:! c.sendMessage(msg)!! def onClose(self):! clients.remove(self)!

example.py

How is this called?

Page 21: What Is Async, How Does It Work, And When Should I Use It?

Let’s look at this

example.py

factory = WebSocketServerFactory(! "ws://localhost:8888")!!factory.protocol = ChatProtocol!!loop = asyncio.get_event_loop()!asyncio.Task(! loop.create_server(factory, '127.0.0.1', 8888))!!loop.run_forever()!

Page 22: What Is Async, How Does It Work, And When Should I Use It?

class BaseEventLoop(events.AbstractEventLoop):! def create_server(! self, protocol_factory, host, port):!! sock = socket.socket(...)! sock.bind(...)! sock.listen()! sock.setblocking(False)!! fd = sock.fileno()! self._selector.register(! fd,! selectors.EVENT_READ,! (self._accept_connection, None))!Magic

Let’s look at this

asyncio

reader, writer

Page 23: What Is Async, How Does It Work, And When Should I Use It?

asyncio

class BaseEventLoop(events.AbstractEventLoop):! def _accept_connection(! self, protocol_factory, sock):! conn, addr = sock.accept()! conn.setblocking(False)!! protocol = protocol_factory()! _SelectorSocketTransport(! self, conn, protocol)!

class _SelectorSocketTransport(_SelectorTransport):! def __init__(self, loop, sock, protocol):! super().__init__(loop, sock, protocol)! self._protocol.connection_made(self)!

ChatProtocol

This was our goal

Page 24: What Is Async, How Does It Work, And When Should I Use It?

asyncio

class BaseEventLoop(events.AbstractEventLoop):! def _accept_connection(! self, protocol_factory, sock):! conn, addr = sock.accept()! conn.setblocking(False)!! protocol = protocol_factory()! _SelectorSocketTransport(! self, conn, protocol)!

But how exactly is this called?

Page 25: What Is Async, How Does It Work, And When Should I Use It?

Let’s look at this

example.py

factory = WebSocketServerFactory(! "ws://localhost:8888")!!factory.protocol = ChatProtocol!!loop = asyncio.get_event_loop()!asyncio.Task(! loop.create_server(factory, '127.0.0.1', 8888))!!loop.run_forever()!

Page 26: What Is Async, How Does It Work, And When Should I Use It?

asyncio

magicclass BaseEventLoop(events.AbstractEventLoop):! def run_forever(self):! while True:! event_list = self._selector.select()!! for fd, mask, data in event_list:! reader, writer = data!! if reader and mask & EVENT_READ:! self._ready.append(reader)!! if writer and mask & EVENT_WRITE:! self._ready.append(writer)!! ntodo = len(self._ready)! for i in range(ntodo):! callback = self._ready.popleft()! callback()!

accept_connection

Page 27: What Is Async, How Does It Work, And When Should I Use It?

Application asyncio’s event loop

start_server()

register(fd,! accept_connection)

accept_connection()

run_forever()

onConnect()

Page 28: What Is Async, How Does It Work, And When Should I Use It?

Review

• asyncio uses non-blocking sockets. !

• Event loop tracks sockets, and the callbacks waiting for them. !

• selectors: wait for network events. !

• Event loop runs callbacks.

Page 29: What Is Async, How Does It Work, And When Should I Use It?

Should I Use It?

Yes: • Slow backend • Websockets • Many connections

29

No: • CPU-bound • No async driver • No async expertise

🍕

Page 30: What Is Async, How Does It Work, And When Should I Use It?

A. Jesse Jiryu Davis

@jessejiryudavis

MongoDB