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

1,363 views
1,062 views

Published on

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.

Published in: Technology, Education
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,363
On SlideShare
0
From Embeds
0
Number of Embeds
94
Actions
Shares
0
Downloads
38
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

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

  1. 1. What Is Async, How Does It Work, A. Jesse Jiryu Davis 
 @jessejiryudavis 
 MongoDB When Should I Use It? &
  2. 2. Food in NYC • Subs • Pizza • Omakase
  3. 3. Subs Counter ⚇! client ⚇! sandwich! maker pool ☺
  4. 4. CPU-bound web app Client ServerClients • Throughput bound by computation
 • No async
  5. 5. Pizza 5 Counter ⚇! client ⚇! pizza
 cook ☺ oven 🍕 ⚇⚇⚇
  6. 6. Normal web app Client Server • Throughput bound by memory
 • Async Backend Database, OAuth service, etc. Clients
  7. 7. Omakase 7 Counter ⚇! waiter kitchen ⚇⚇⚇! clients
  8. 8. Websocket application Client Server sockets Events sockets Clients • Number of clients bound by memory
 • Async
  9. 9. What’s async for? Minimizes resources per connection.
  10. 10. C10K kegel.com/c10k.html
  11. 11. Why is async hard to code? BackendClient Server request response store state request response time
  12. 12. Why is async hard to code? BackendClient Server websocket event store state register for events event time
  13. 13. Ways to store state: Coding difficulty Threads Callbacks Memoryperconnection
  14. 14. Ways to store state: • Threads • Callbacks ! ... and: ! • Coroutines • Greenlets ! and so on....
  15. 15. So, what is async? • Single-threaded • I/O concurrency
 • Non-blocking sockets • epoll / kqueue • Event loop
  16. 16. asyncio • AKA “Tulip” • Python 3.4 standard library • Implements PEP 3156 • Standard event loop • Coroutines
  17. 17. 17
  18. 18. Layers 18 Application Protocol Transport Event Loop Selectors asyncio { autobahn websockets example.py
  19. 19. from autobahn import (WebSocketServerProtocol,! WebSocketServerFactory)! example.py
  20. 20. 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?
  21. 21. 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()!
  22. 22. 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
  23. 23. 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
  24. 24. 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?
  25. 25. 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()!
  26. 26. asyncio magic class 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
  27. 27. Application asyncio’s event loop start_server() register(fd,! accept_connection) accept_connection() run_forever() onConnect()
  28. 28. 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.
  29. 29. Should I Use It? Yes: • Slow backend • Websockets • Many connections 29 No: • CPU-bound • No async driver • No async expertise 🍕
  30. 30. A. Jesse Jiryu Davis 
 @jessejiryudavis 
 MongoDB

×