Taking Django Async

Taking Django Async

A talk I gave at PyCon US 2018

077e9a0cb34fa3eba2699240c9509717?s=128

Andrew Godwin

May 11, 2018
Tweet

Transcript

  1. 2.

    Hi, I’m Andrew Godwin • Django core team member •

    Senior Software Engineer at • Does network programming for "fun"
  2. 8.

    Webserver (Twisted) Django (Sync worker process) Clients Channel Layer (Redis

    or other) Webserver (Twisted) Django (Sync worker process)
  3. 14.
  4. 19.

    WSGI Handler (WSGI-to-request translator) URL Routing (path to view mapping)

    Django Middleware (auth, sessions, etc) Views (logic and presentation) ORM (database kerfuffling)
  5. 20.

    ASGI Handler (ASGI-to-request translator) URL Routing (path to view mapping)

    Django Middleware (auth, sessions, etc.) Views (logic and presentation) ORM (database kerfuffling)
  6. 21.

    ASGI Handler (ASGI-to-request translator) URL Routing (path to view mapping)

    Django Middleware (auth, sessions, etc.) Views (logic and presentation) ORM (database kerfuffling) ASGI Routing (path/protocol/etc. mapping) ASGI Middleware (auth, sessions, etc.) Consumers (logic and presentation) synchronous
  7. 23.
  8. 30.

    Async code runs on the event loop We need to

    go find it! Or make our own.
  9. 31.

    # Make a future for the return information call_result =

    Future() # Use call_soon_threadsafe to schedule a synchronous callback on the # main event loop's thread if not (self.main_event_loop and self.main_event_loop.is_running()): # Make our own event loop and run inside that. loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(self.main_wrap(args, kwargs, call_result)) finally: try: if hasattr(loop, "shutdown_asyncgens"): loop.run_until_complete(loop.shutdown_asyncgens()) finally: loop.close() asyncio.set_event_loop(self.main_event_loop) else: self.main_event_loop.call_soon_threadsafe( self.main_event_loop.create_task, self.main_wrap( args, kwargs, call_result, ), ) # Wait for results from the future. return call_result.result()
  10. 32.

    Make a Future Jump to the main thread and add

    the coroutine Tie the coroutine's end to triggering the Future Block the thread on the Future
  11. 35.

    ASGI Handler (ASGI-to-request translator) URL Routing (path to view mapping)

    Django Middleware (auth, sessions, etc.) Views (logic and presentation) ORM (database kerfuffling) ASGI Routing (path/protocol/etc. mapping) ASGI Middleware (auth, sessions, etc.) Consumers (logic and presentation) synchronous
  12. 37.

    ASGI: It's like WSGI but with an A in it

    Also asyncio and stuff like that
  13. 39.
  14. 45.
  15. 47.

    Do we want to have everyone writing async? What's the

    balance? How do we be flexible enough?