what is async, how does it work, and when should i use it?

Post on 10-May-2015

552 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

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.

TRANSCRIPT

What Is Async, How Does It Work,

A. Jesse Jiryu Davis

@jessejiryudavis

MongoDB

When Should I Use It?&

Food in NYC

• Subs

• Pizza

• Omakase

Subs

Counter

⚇!client

⚇!sandwich!maker

pool☺

CPU-bound web app

Client ServerClients

• Throughput bound by computation• No async

Pizza

5

Counter

⚇!client

⚇!pizza cook

oven🍕

⚇⚇⚇

Normal web app

Client Server

• Throughput bound by memory • Async

Backend Database,

OAuth service, etc.

Clients

Omakase

7

Counter

⚇!waiter

kitchen

⚇⚇⚇!clients

Websocket application

Client Serversockets

EventssocketsClients

• Number of clients bound by memory • Async

What’s async for?

Minimizes resources per connection.

C10K

kegel.com/c10k.html

Why is async hard to code?BackendClient Server

request

response

store state

request

response

time

Why is async hard to code?BackendClient Server

websocket

event

store state

register for events

event

time

Ways to store state:

Coding difficulty

Threads

Callbacks

Mem

ory

per

co

nn

ectio

n

Ways to store state:

• Threads • Callbacks !

... and: !

• Coroutines • Greenlets !

and so on....

So, what is async?

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

asyncio

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

17

Layers

18

Application

Protocol

Transport

Event Loop

Selectors

asyncio{autobahn websockets

example.py

from autobahn import (WebSocketServerProtocol,! WebSocketServerFactory)!

example.py

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?

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()!

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

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

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?

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()!

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

Application asyncio’s event loop

start_server()

register(fd,! accept_connection)

accept_connection()

run_forever()

onConnect()

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.

Should I Use It?

Yes: • Slow backend • Websockets • Many connections

29

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

🍕

A. Jesse Jiryu Davis

@jessejiryudavis

MongoDB

top related