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

Django 3.2 ASGI対応 - こわくない asyncio 基礎とasync viewの使い所

Django 3.2 ASGI対応 - こわくない asyncio 基礎とasync viewの使い所

DjangoCongressJP 2021 の登壇資料です。

Junya Fukuda

July 03, 2021
Tweet

More Decks by Junya Fukuda

Other Decks in Programming

Transcript

  1. •෱ా ൏໵ʢJunya Fukudaʣʢ@JunyaFffʣ •גࣜձࣾ೔ຊγεςϜٕݚʢJSLʣॴଐ ௕໺ݝͷձࣾ •WebΤϯδχΞ •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ •Effective

    Python ͷಡॻձ΍ͬͯ·͢ 📚 •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε •ຊ޷͖ʹѪ͞ΕΔαʔϏεΛ໨ࢦͯ͠ʢݹຊങऔɾൢചʣ ΪʔΫϥϘ௕໺ಡॻձ
  2. •Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress JP Django 3.2 •Django 3 ͷ໨ۄͷ1ͭ •Django

    3.0 - ASGIରԠ •Django 3.1 - Async View, ϛυϧ΢ΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ
  3. •Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress Django 3.2 •Django 3 ͷ໨ۄͷ1ͭ •Django 3.0

    - ASGIରԠ •Django 3.1 - Async View, ϛυϧ΢ΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ
  4. •Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress Django 3.2 •Django 3 ͷ໨ۄͷ1ͭ •Django 3.0

    - ASGIରԠ •Django 3.1 - Async View, ϛυϧ΢ΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ •Django 3.x or 4? - Async ORM
  5. Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn ΍ uWSGI ⁶

    Django ΍ Flask, Pyramid •Uvicorn ΍ Hypercorn ⁶ Django ΍ FastAPI, Starlette って?
  6. Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn ΍ uWSGI ⁶

    Django ΍ Flask, Pyramid •Uvicorn ΍ Hypercorn ⁶ Django ΍ FastAPI, Starlette •WSGIͱASGIɺͳʹ͕ҧ͏ͷ͔ って? WSGI
  7. •Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress Django 3.2 •Django 3 ͷ໨ۄͷ1ͭ •Django 3.0

    - ASGIରԠ •Django 3.1 - Async View, ϛυϧ΢ΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ •Django 3.x or 4? - Async ORM
  8. •Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress Django 3.2 •Django 3 ͷ໨ۄͷ1ͭ •Django 3.0

    - ASGIରԠ •Django 3.1 - Async View, ϛυϧ΢ΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ •Django 3.x or 4? - Async ORM asyncioରԠ
  9. 本⽇のおしながき •Django 3.1 - Async View ͷ࢖͍ॴ •Django 3.x or

    4? - Async ORM •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ
  10. •asyncio͜Θ͍ͳ͋… •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ •Django ORM ΋͍͚Δͷʁʁ •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋

    👋 •Django async view ͬͯͦ͏͍͏ͱ͖Ͷ 🙌 •Django async ORM ͨͷ͠Έͩͳ͋ʙ ✊
  11. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ
  12. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO
  13. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic
  14. •͜Θ͔ͬͨ •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ •Using Asyncio in

    Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍
  15. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic
  16. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic
  17. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic
  18. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
  19. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio
  20. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド
  21. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ
  22. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ 同じ⼈
  23. 並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔
  24. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه

    •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic γϯάϧεϨου ฒߦॲཧ ඇಉظ IO
  25. 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ

    注⽂を取る - 料理を作る - 料理を運ぶ asyncio コルーチンやタスク
  26. asyncio 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -

    料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ コルーチンやタスク
  27. async def customers_long_thinking_order(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep() return “͟Δͦ͹” await の動作を確認する

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order() menu2 = await customers_long_thinking_order() menu2 = await customers_long_thinking_order() print([menu1, memu2, menu3])
  28. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return “͟Δͦ͹” async

    def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order() menu2 = await customers_long_thinking_order() menu2 = await customers_long_thinking_order() print([menu1, memu2, menu3]) await の動作を確認する
  29. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) menu2 = await customers_long_thinking_order(2) menu3 = await customers_long_thinking_order(3) print([menu1, memu2, menu3]) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order())
  30. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) menu2 = await customers_long_thinking_order(2) menu3 = await customers_long_thinking_order(3) print([menu1, memu2, menu3]) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  ͟Δͦ͹   ͟Δͦ͹   ͟Δͦ͹ > UJNF
  31. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) print(menu1) menu2 = await customers_long_thinking_order(2) print(menu2) menu3 = await customers_long_thinking_order(3) print(menu3) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order())
  32. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) print(menu1) menu2 = await customers_long_thinking_order(2) print(menu2) menu3 = await customers_long_thinking_order(3) print(menu3) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹  ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹  ͪΐͬͱ଴ͬͯͶ  b͟Δͦ͹  UJNF
  33. async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

    async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) print(menu1) menu2 = await customers_long_thinking_order(2) print(menu2) menu3 = await customers_long_thinking_order(3) print(menu3) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) コルーチンをawaitするだけでは 並⾏にならない 1つのコルーチンが終わってから 次のコルーチン 普通の関数実⾏ と同じ l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹  ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹  ͪΐͬͱ଴ͬͯͶ  b͟Δͦ͹  UJNF
  34. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) menu2 = await customers_long_thinking_order(2) menu3 = await customers_long_thinking_order(3) print([menu1, memu2, menu3]) asyncio.run(order())
  35. 初めてのタスク async def order(): print(“͝஫จ͸ʁ”) menu1 = await customers_long_thinking_order(1) menu2

    = await customers_long_thinking_order(2) menu3 = await customers_long_thinking_order(3) print([menu1, memu2, menu3]) asyncio.run(order()) async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”
  36. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 menu1 = await task2 menu1 = await task3 print([menu1, memu2, menu3]) asyncio.run(order())
  37. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 menu1 = await task2 menu1 = await task3 print([menu1, memu2, menu3]) asyncio.run(order()) 実⾏してみましょう
  38. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 menu2 = await task2 menu3 = await task3 print([menu1, memu2, menu3]) asyncio.run(order()) 実⾏してみましょう ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  ͟Δͦ͹   ͟Δͦ͹   ͟Δͦ͹ > UJNF
  39. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう
  40. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹   ͟Δͦ͹   ͟Δͦ͹  UJNF
  41. 初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num,

    “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(customers_long_thinking_order(1)) task2 = asyncio.create_task(customers_long_thinking_order(2)) task3 = asyncio.create_task(customers_long_thinking_order(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ  ͟Δͦ͹   ͟Δͦ͹   ͟Δͦ͹  UJNF
  42. gatherを利⽤して結果をまとめて受け取る async def customers_long_thinking_order(num: int): print("ͪΐͬͱ଴ͬͯͶ") await asyncio.sleep(num) return num,

    "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [ customers_long_thinking_order(3000), customers_long_thinking_order(200), customers_long_thinking_order(10), ] result = await asyncio.gather(*tasks) print(result) asyncio.run(order())
  43. gatherを利⽤して結果をまとめて受け取る async def customers_long_thinking_order(num: int): print("ͪΐͬͱ଴ͬͯͶ") await asyncio.sleep(num) return num,

    "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [ customers_long_thinking_order(3000), customers_long_thinking_order(200), customers_long_thinking_order(10), ] result = await asyncio.gather(*tasks) print(result) asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  ͟Δͦ͹   ͟Δͦ͹   ͟Δͦ͹ > UJNF
  44. 考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return

    num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start)
  45. 考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return

    num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  3FTQPOTF<> b͟Δͦ͹` > UJNF
  46. 考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return

    num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  3FTQPOTF<> b͟Δͦ͹` > UJNF
  47. 考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return

    num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET  3FTQPOTF<> ͟Δͦ͹ > UJNF
  48. 考え中のお客様がgoogle検索 async def long_think(client, num: int): print("ͪΐͬͱ଴ͬͯͶ") response = await

    client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client, 1), long_think(client, 2), long_think(client, 3)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start)
  49. 考え中のお客様がgoogle検索 async def long_think(client, num: int): print("ͪΐͬͱ଴ͬͯͶ") response = await

    client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client, 1), long_think(client, 2), long_think(client, 3)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ <  3FTQPOTF<0,> b͟Δͦ͹`  UJNF
  50. ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(coro) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ)

    - ·ͱΊͯ݁ՌΛड͚औΕΔ async def hoge() await λεΫ ·ͨ͸ ίϧʔνϯ asynio.run(ίϧʔνϯ) ༨ྗ͕͋Ε͹ɺget_running_loop()ͬͯͷ΋ 🙏
  51. ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(coro) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ)

    - ·ͱΊͯ݁ՌΛड͚औΕΔ async def hoge() await λεΫ ·ͨ͸ ίϧʔνϯ asynio.run(ίϧʔνϯ) ༨ྗ͕͋Ε͹ɺget_running_loop()ͬͯͷ΋ 🙏 まずはこれを抑えましょう
  52. 本⽇のおしながき •Django 3.1 - Async View •Django 3.x or 4?

    - Async ORM •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ
  53. Django Async View の使い所 •ιʔεͷྫ async def long_think(client, num: int):

    print("ͪΐͬͱ଴ͬͯͶ") response = await client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def async_view(request): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client) for i in range(10)] result = await asyncio.gather(*tasks) return HttpResponse(result)
  54. Django Async View の使い所 •ιʔεͷྫ async def long_think(client, num: int):

    print("ͪΐͬͱ଴ͬͯͶ") response = await client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def async_view(request): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client) for i in range(10)] result = await asyncio.gather(*tasks) return HttpResponse(result) BTZODJPSVO ͸͠ͳ͍ͷʁ🤔
  55. Django Async View の使い所 •Έͳ͞Μ΋͏ͯ͠·͢ɻ •஌Βͣ஌Βͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏΍࣮ͬͯߦ͠·͔͢ʁ $

    uvicorn hello_async_world.asgi:application •ASGIͰɺPythonͷWebαʔόͱPythonͷWeb FWΛܨ͍ͰΔ
  56. Django Async View の使い所 •Έͳ͞Μ΋͏ͯ͠·͢ɻ •஌Βͣ஌Βͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏΍࣮ͬͯߦ͠·͔͢ʁ $

    uvicorn hello_async_world.asgi:application •ASGIͰɺPythonͷWebαʔόͱPythonͷWeb FWΛܨ͍ͰΔ •ASGIαʔόଆͰΠϕϯτϧʔϓΛ࣮ߦ͍ͯ͠Δ
  57. Django Async View の使い所 •sync_to_async() ಉظؔ਺Λड͚औΓɺͦΕΛϥοϓͯ͠ඇಉظؔ਺Λฦ͠·͢ɻ ௚઀ϥούʔ·ͨ͸σίϨʔλͱͯ͠࢖༻Ͱ͖·͢ɻ async_function = sync_to_async(sync_function,

    thread_sensitive=False) async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True) @sync_to_async def sync_function(...): ... IUUQTEPDTEKBOHPQSPKFDUDPNFOUPQJDTBTZODTZODUPBTZOD
  58. Django Async View の使い所 •sync_to_async() asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ࿥͢Δ͜ͱ͕Ͱ͖·͢ɻ ʢDjangoʹݶͬͨ࿩Ͱ͸ͳ͘ʣ concurrent.futures Ϟδϡʔϧ ʢthreading

    ͱ multiprocessing Λ༰қʹ࢖͑Δඪ४ϥΠϒϥϦʣ ͜ΕͰඇಉظʹͰ͖Δ…ʹ͸Ͱ͖·͕͢ɺ ࣮ߦʹίετ͕͔͔Γ଎౓ʹӨڹ͕ଟগ͋Γ·͢ɻ
  59. Async ORM •Async ORM ΁ͷಓ •PyConline AU 2020 "Taking Django's

    ORM Async” •Django ίΞ developer Andrew Godwin ͞Μ
  60. まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •Django async view - ಉظͱඇಉظ߹Θͤͯ IOό΢ϯυͳॲཧΛத৺ʹ…

    •Async ORM - ָ͠ΈͰ͢Ͷʂ ʢPyhtonͰ͸ asyncio ରԠͷORM΍Ξμϓλʔ΋͢Ͱʹ͍͔ͭ͋͘Γ·͢ɻʣ ·ͨɺDjango͸OSSͰ͢ɻϦϙδτϦΛͷ͍ͧͯΈΔͷ΋ྑ͍͔΋͠Ε·ͤΜ 👀 IUUQTHJUIVCDPNEKBOHPEKBOHP
  61. •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer •Using Asyncio in Python -

    Oreilly & Associates Inc 参考 •Better Examples of Django Async Views •https://dev.to/arocks/better-examples-of-django-async-views-295d •asyncioͷTaskʹؔ͢Δجૅ஌ࣝ •https://aish.dev/python/20200711_asyncio_task.html •DjangoCon 2020 | How To Break Django: With Async - Andrew Godwin •https://www.youtube.com/watch?v=19Uh_PA_8Rc •"Taking Django's ORM Async" - Andrew Godwin (PyConline AU 2020) •https://youtu.be/ibAmA4QQDhs