The Long Road To Asynchrony

The Long Road To Asynchrony

My keynote from PyCon Belarus 2020.

077e9a0cb34fa3eba2699240c9509717?s=128

Andrew Godwin

February 22, 2020
Tweet

Transcript

  1. 2.

    Andrew Godwin / @andrewgodwin Hi, I’m Andrew Godwin • Django

    core developer • Worked on Migrations, Channels & Async • Once a Londoner, now from Denver, USA
  2. 10.

    Andrew Godwin / @andrewgodwin func main() { messages := make(chan

    string) go func() { messages <- "ping" }() msg := <-messages fmt.Println(msg) }
  3. 14.
  4. 16.

    Andrew Godwin / @andrewgodwin # Ready when a timer finishes

    await asyncio.sleep(1) # Ready when network packets return await client.get("http://example.com") # Ready when the coroutine exits await my_function("hello", 64.2)
  5. 17.

    Andrew Godwin / @andrewgodwin Network/timer updates An event loop's flow

    Select a ready task Run task Add new tasks to queue await
  6. 20.

    Andrew Godwin / @andrewgodwin 1998 threading module, Stackless Python 2002

    Twisted 2006 Greenlets (later gevent, eventlet) 2008 multiprocessing module 2012 Tulip, PEP 3156 2014 asyncio module 2005 Coroutine-friendly generators (PEP 342)
  7. 21.

    Andrew Godwin / @andrewgodwin 2017 Django Channels 1.0 2018 Django

    Channels 2.0 2019 DEP 9 (Async support) 2020 Async views land in Django
  8. 23.

    Andrew Godwin / @andrewgodwin Asyncio is based on yield from

    Because it was prototyped in Python 2
  9. 24.

    Andrew Godwin / @andrewgodwin Can't tell if a function returns

    a coroutine! There are standard hints, but no actual guaranteed way
  10. 25.

    Andrew Godwin / @andrewgodwin async def calculate(x): result = await

    coroutine(x) return result # These both return a coroutine def calculate(x): result = coroutine(x) return result
  11. 26.

    Andrew Godwin / @andrewgodwin Can't have one function service both

    How we got here makes sense, but it's still annoying sometimes.
  12. 27.

    Andrew Godwin / @andrewgodwin # Calls get.__call__ instance = MyModel.objects.get(id=3)

    # Calls get.__call__ # and then awaits its result instance = await MyModel.objects.get(id=3)
  13. 28.
  14. 31.

    Andrew Godwin / @andrewgodwin time.sleep ➞ asyncio.sleep requests ➞ httpx

    psycopg2 ➞ aiopg WSGI ➞ ASGI Django ➞ Django?
  15. 33.

    Andrew Godwin / @andrewgodwin Asyncio only benefits IO-bound code Code

    that thrashes the CPU doesn't benefit at all
  16. 35.

    Andrew Godwin / @andrewgodwin But, you can't mix sync and

    async So we have to have two parallel request paths
  17. 36.

    Andrew Godwin / @andrewgodwin WSGIHandler __call__ WSGI Server WSGIRequest BaseHandler

    get_response URLs Middleware View __call__ HTTP protocol Socket handling Transfer encodings Headers-to-META Upload file wrapping GET/POST parsing Exception catching Atomic view wrapper Django 3.0 Request Flow
  18. 37.

    Andrew Godwin / @andrewgodwin WSGIHandler __call__ WSGI Server WSGIRequest BaseHandler

    get_response URLs Middleware Async View __call__ ASGIHandler __call__ ASGI Server ASGIRequest Sync View __call__ Asynchronous request path Proposed async request flow
  19. 38.

    Andrew Godwin / @andrewgodwin WSGIHandler __call__ WSGI Server WSGIRequest URLs

    Middleware View __call__ ASGIHandler __call__ ASGI Server ASGIRequest Asynchronous request path BaseHandler get_response_async BaseHandler get_response URLs Middleware Async View __call__ Implemented async request flow
  20. 39.

    Andrew Godwin / @andrewgodwin We have to work with what

    we have I'd rather let people ship code than argue about perfection.
  21. 42.

    Andrew Godwin / @andrewgodwin Coroutines & the GIL actually help!

    You're saved from all the awful memory corruption bugs
  22. 43.

    Andrew Godwin / @andrewgodwin async def transfer_money(p1, p2): await get_lock()

    # Code between awaits is atomic! subtract_money(p1) add_money(p2) await release_lock()
  23. 44.

    Andrew Godwin / @andrewgodwin You can still screw up a

    lot Trust me, I have lived it while developing async
  24. 47.

    Andrew Godwin / @andrewgodwin Async usability has a long way

    to go But it is undoubtedly the future!
  25. 50.

    Andrew Godwin / @andrewgodwin Let's make async understandable Almost every

    project could benefit, if we made it worth their time.