Upgrade to Pro — share decks privately, control downloads, hide ads and more …

async def django(): (French version)

async def django(): (French version)

DEP0009 : La proposition d’Andrew Godwin d’ajouter le support asynchrone à Django a été acceptée en Juillet. En quoi consiste-t-elle ? Que va-t-elle changer ? Et comment participer à la transition ?

Joachim Jablon

September 13, 2019
Tweet

More Decks by Joachim Jablon

Other Decks in Programming

Transcript

  1. Qui a déjà..? "#$%& Entendu parler d'Andew Godwin ? Lu

    du code Python asynchrone ? Ecrit du code Python Asynchrone ? Lu la DEP 0009 ?
  2. Que fait votre serveur web ? Des I/Os (réseau /

    disque) Des cycles CPU (calculs) Python délègue
 à l'OS (appel système) Python parle au CPU directement Python sait
 le paralléliser dans des threads Python ne sait pas le paralléliser ( GIL ) >90%* <10%* *au doigt mouillé
  3. Les threads & Python Serveur qui envoie du pâté (végan

    ) 100+ requêtes simultanées 100 threads ☠ Context Switching & GIL
  4. Et si les threads coopéraient ? La partie CPU s'exécute

    sans interruption Quand elle lance un IO, elle s'interrompt,
 et laisse la place a une autre partie CPU L'IO s'exécute en tâche de fond,
 quand il est fini, il indique
 que le CPU peut reprendre Boucle d'évènements CPU I/O A A A A A B B B C C C
  5. async / await async def view(request: Request) -> Response: user

    = await orm.get_user(id=request.id) return JsonResponse({"hello": user.full_name})
  6. Appels def func(): a = sync_network() def func(): a =

    asyncio.run( async_network() ) async def coro(): a = await loop.run_in_executor( ThreadPoolExecutor(), sync_network ) async def coro(): a = await async_network() Appeler du code: Synchrone Asynchrone Depuis
 du code: Synchrone Asynchrone
  7. Contre-exemples ❌ async def coro(): sync_network() async def coro(): k

    = 1 for i in range(1, 1e32): k *= i ** i def func(): await async_network() def func(): async_network()
  8. A A A A A A B B B C

    C C A a oublié d'appeler ses I/O en asynchrones A A A B C C A C L'exemple de tout a l'heure CPU I/O A A A A A B B B C C C B lance une tâche gourmande en CPU
  9. WSGI Une application est un callable Reçoit une requête HTTP,

    renvoie la réponse HTTP Plutôt adapté pour HTTP (mais un peu vieillot)
  10. Rendre Django
 compatible ASGI et async Et résoudre la faim

    et la paix dans le monde tant qu'à y être...
  11. La structure de Django WSGI Server View Middleware Handler URL

    router Form Template ORM From "Just Add Await: Retrofitting Async Into Django" - Andrew Godwin (PyCon AU 2019)
  12. Phase 3 ORM async Phase 2: vues async Phase 1

    Serveur async Le plan ASGI/WSGI Server View Middleware Handler URL router Form Template ORM From "Just Add Await: Retrofitting Async Into Django" - Andrew Godwin (PyCon AU 2019) Phase 4+
 le reste
  13. Phase 1: ASGI Bien aidé par le le couplage faible

    entre WSGI et Django:
 WSGIHandler / BaseHandler
 
 ASGIHandler Point de passage async vers sync
  14. (r)Appels a = sync_func() a = asyncio.run( async_func() ) a

    = await loop.run_in_executor( ThreadPoolExecutor(), sync_func ) a = await async_func() Appeler du code: Synchrone Asynchrone Depuis
 du code: Synchrone Asynchrone
  15. Résultat Ca marche C'est plus rapide si vous avez des

    uploads lents C'est déjà mergé dans Django 3
  16. Phase 3 ORM async Phase 2: vues async Phase 1

    Serveur async Le plan ASGI/WSGI Server View Middleware Handler URL router Form Template ORM From "Just Add Await: Retrofitting Async Into Django" - Andrew Godwin (PyCon AU 2019) Phase 4+
 le reste
  17. Phase 2: Vues asynchrones Handler asynchrone capable de lancer: 


    - des vues synchrones (sync_to_async)
 - ou asynchrones Travail en cours, peut-etre en Django 3.1 async def my_view(request):
  18. Le problème des Middlewares Cas 1 Middleware1> Middleware2> Middleware3> Middleware4>


    Cas 2 Middleware1> Middleware2> Middleware3> Middleware4>
 Cas 3 Middleware1> Middleware2> Middleware3> Middleware4>
  19. Le problème des Middlewares Cas 1 Middleware1> Middleware2> Middleware3> Middleware4>


    Cas 2 Middleware1> Middleware2> a2s>Middleware3>s2a> Middleware4>
 Cas 3 Middleware1> a2s>Middleware2>s2a> a2s>Middleware3>s2a> Middleware4>
  20. Le problème des Middlewares Cas 1 Middleware1> Middleware2> Middleware3> Middleware4>


    Cas 2 Middleware1> Middleware2> a2s>Middleware3>s2a> Middleware4>
 Cas 3 Middleware1> a2s>Middleware2>s2a> a2s>Middleware3>s2a> Middleware4>
  21. Le problème des Templates Un template peut appeler de l'IO

    (lecture du disque) Une exception peut provoquer un template (500, 404...)
  22. Phase 3 ORM async Phase 2: vues async Phase 1

    Serveur async Le plan ASGI/WSGI Server View Middleware Handler URL router Form Template ORM From "Just Add Await: Retrofitting Async Into Django" - Andrew Godwin (PyCon AU 2019) Phase 4+
 le reste
  23. Phase 3: L'ORM for result in Model.objects.all(): async for result

    in Model.objects.all(): instance.foreign_key
  24. Phase 4: La stratégie 1. coeur sync, utiliser sync_to_async partout

    2. coeur async, async_to_sync partout 3. Ne pas tout casser
  25. Phase 3 ORM async Phase 2: vues async Phase 1

    Serveur async Le plan ASGI/WSGI Server View Middleware Handler URL router Form Template ORM From "Just Add Await: Retrofitting Async Into Django" - Andrew Godwin (PyCon AU 2019) Phase 4+
 le reste