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. Django 3.2 ASGI対応
    Junya Fukuda
    DjangoCongress JP 2021
    -こわくない asyncio 基礎とasync viewの使い所

    View Slide

  2. •෱ా ൏໵ʢJunya Fukudaʣʢ@JunyaFffʣ


    •גࣜձࣾ೔ຊγεςϜٕݚʢJSLʣॴଐ ௕໺ݝͷձࣾ


    •WebΤϯδχΞ


    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ


    •Effective Python ͷಡॻձ΍ͬͯ·͢ 📚


    •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε


    •ຊ޷͖ʹѪ͞ΕΔαʔϏεΛ໨ࢦͯ͠ʢݹຊങऔɾൢചʣ
    ΪʔΫϥϘ௕໺ಡॻձ

    View Slide

  3. こんにちは⻑野!

    View Slide

  4. ハイブリット開催ですね🎉
    (オンライン&オフライン)

    View Slide

  5. ハイブリット開催ですね🎉
    (オンライン&オフライン)
    わたしは初めてのオフラインです。

    View Slide

  6. オフラインのひと〜👋

    View Slide

  7. オンラインのひと〜👋

    View Slide

  8. 🙌

    View Slide

  9. Django 3.2

    View Slide

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

    View Slide

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

    View Slide

  12. •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

    View Slide

  13. Django 3.0 - ASGI対応
    •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷
    って?

    View Slide

  14. Django 3.0 - ASGI対応
    •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷
    •WSGIͷਫ਼ਆతޙܧ
    って?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  18. WSGI

    View Slide

  19. WSGI Web Server Gateway Interface

    View Slide

  20. WSGI Web Server Gateway Interface
    ASGI

    View Slide

  21. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface

    View Slide

  22. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface

    View Slide

  23. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface
    ⾮同期

    View Slide

  24. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface
    ⾮同期
    ASGI= asyncio

    View Slide

  25. •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

    View Slide

  26. •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ରԠ

    View Slide

  27. 本⽇のおしながき
    •Django 3.1 - Async View ͷ࢖͍ॴ
    •Django 3.x or 4? - Async ORM
    •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ

    View Slide

  28. •asyncio͜Θ͍ͳ͋…
    •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ
    •Django ORM ΋͍͚Δͷʁʁ

    View Slide

  29. •asyncio͜Θ͍ͳ͋…
    •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ
    •Django ORM ΋͍͚Δͷʁʁ
    •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋

    View Slide

  30. •asyncio͜Θ͍ͳ͋…
    •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ
    •Django ORM ΋͍͚Δͷʁʁ
    •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋
    •Django async view ͬͯͦ͏͍͏ͱ͖Ͷ 🙌

    View Slide

  31. •asyncio͜Θ͍ͳ͋…
    •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ
    •Django ORM ΋͍͚Δͷʁʁ
    •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋
    •Django async view ͬͯͦ͏͍͏ͱ͖Ͷ 🙌
    •Django async ORM ͨͷ͠Έͩͳ͋ʙ ✊

    View Slide

  32. すべてはasync/awaitから始まった

    View Slide

  33. >
    IUUQT
    fl
    PSJNPOEEFWCMPHBSUJDMFTJOUSPEVDUJPOUPBTHJBTZODQZUIPOXFC
    すべてはasync/awaitから始まった

    View Slide

  34. asyncioはこわくない

    View Slide

  35. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ
    asyncioはこわくない

    View Slide

  36. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ
    •Python 3.5 Ͱ async/await ߏจ
    asyncioはこわくない

    View Slide

  37. •Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ
    •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه
    •Python 3.5 Ͱ async/await ߏจ
    asyncioはこわくない

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  41. asyncio めっちゃこわい

    View Slide

  42. •͜Θ͔ͬͨ
    asyncio めっちゃこわい

    View Slide

  43. •͜Θ͔ͬͨ
    •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ
    •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ
    asyncio めっちゃこわい
    •2ͭͷग़ձ͍

    View Slide

  44. •asyncio ͸௒ڊେ
    対象はアプリーケーション開発者

    View Slide

  45. •asyncio ͸௒ڊେ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ

    View Slide

  46. •asyncio ͸௒ڊେ
    •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ

    View Slide

  47. •asyncio ͸௒ڊେ
    •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏
    •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ

    View Slide

  48. •asyncio ͸௒ڊେ
    •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏
    •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ
    •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠಺༰Ͱ͢

    View Slide

  49. •asyncio ͸௒ڊେ
    •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏
    •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ
    •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠asyncio
    •લఏ஌ࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ

    View Slide

  50. •asyncio ͸௒ڊେ
    •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏
    •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ
    対象はアプリーケーション開発者
    •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ
    •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠asyncio
    •લఏ஌ࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. ⾔葉を完全に理解する

    View Slide

  55. IUUQTEPDTQZUIPOPSHKBMJCSBSZBTZODJPIUNM

    View Slide

  56. 前提知識
    並⾏処理

    View Slide

  57. 前提知識
    並⾏処理
    並列処理

    View Slide

  58. 前提知識
    並⾏処理
    並列処理
    順次処理

    View Slide

  59. 前提知識
    並⾏処理
    並列処理
    順次処理
    タスクの処理

    View Slide

  60. 並⾏処理
    並列処理
    順次処理

    View Slide

  61. 並⾏処理
    並列処理
    順次処理

    View Slide

  62. 並⾏処理
    並列処理
    順次処理

    View Slide

  63. 並⾏処理
    並列処理
    順次処理
    通常の関数を呼び出していく処理

    View Slide

  64. 並⾏処理
    並列処理
    順次処理
    通常の関数を呼び出していく処理
    multiprocessingモジュール

    View Slide

  65. 並⾏処理
    並列処理
    順次処理
    通常の関数を呼び出していく処理
    multiprocessingモジュール
    threadingモジュール asyncioモジュール

    View Slide

  66. ちょっとわかりにくいので
    レストラン🍽に例えます

    View Slide

  67. レストラン

    View Slide

  68. レストラン
    どんなタスクが
    あるでしょうか

    View Slide

  69. 注⽂をとる

    View Slide

  70. 料理を作る
    注⽂をとる

    View Slide

  71. 料理を作る
    注⽂をとる 料理を運ぶ

    View Slide

  72. 順次処理

    View Slide

  73. 順次処理
    注⽂を取る - 料理を作る - 料理を運ぶ

    View Slide

  74. 順次処理
    注⽂を取る - 料理を作る - 料理を運ぶ
    完了してから次のタスク

    View Slide

  75. 並列処理

    View Slide

  76. 並列処理
    注⽂を取る
    料理を作る
    料理を運ぶ

    View Slide

  77. 並列処理
    注⽂を取る
    料理を作る
    料理を運ぶ
    複数のタスクを同時に着⼿する

    View Slide

  78. 並⾏処理

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  84. 並⾏処理
    注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
    asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔

    View Slide

  85. asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた

    View Slide

  86. asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた お客様

    View Slide

  87. asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた お客様
    ←注⽂

    View Slide

  88. asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた 考え中のお客様
    ←注⽂待ち

    View Slide

  89. asyncio
    シングルスレッド = ワンオペ
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた 考え中のお客様
    ←注⽂待ち
    あなたから⾒て、
    外部のお客様、から
    注⽂という
    ⼊⼒を待つ状態

    View Slide

  90. asyncio
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた 考え中のお客様
    ←注⽂待ち
    あなたから⾒て、
    外部のお客様、から
    注⽂という
    ⼊⼒を待つ状態

    View Slide

  91. a
    どのタイミングでタスクの切り替えをするのでしょうか 🤔
    あなた 考え中のお客様
    ←注⽂待ち
    あなたから⾒て、
    外部のお客様、から
    注⽂という
    ⼊⼒を待つ状態
    ⾮同期IO
    syncio

    View Slide

  92. a sync io

    View Slide

  93. a sync io
    ⼊⼒

    View Slide

  94. a sync io
    同期 ⼊⼒

    View Slide

  95. a sync io
    しない 同期 ⼊⼒

    View Slide

  96. asyncio
    ⾮同期IO

    View Slide

  97. asyncio
    ⾮同期IO

    View Slide

  98. asyncio
    ⾮同期IO

    View Slide

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

    View Slide

  100. ฒߦॲཧ
    asyncioの周辺はちょっとこわくない
    γϯάϧεϨου
    ඇಉظ IO

    View Slide

  101. ฒߦॲཧ
    asyncioの周辺はちょっとこわくない
    γϯάϧεϨου
    ඇಉظ IO

    View Slide

  102. ฒߦॲཧ
    asyncioの周辺はちょっとこわくない
    γϯάϧεϨου
    ඇಉظ IO
    ϫϯΦϖ

    View Slide

  103. ฒߦॲཧ
    asyncioの周辺はちょっとこわくない
    γϯάϧεϨου
    ඇಉظ IO
    ϫϯΦϖ
    外部のお客様、から
    注⽂という
    ⼊⼒を待たないで他のことする

    View Slide

  104. asyncio

    View Slide

  105. asyncio🌷

    View Slide

  106. asyncio で
    覚えておくことは3つ
    asyncio

    View Slide

  107. イベントループ

    View Slide

  108. コルーチン
    イベントループ

    View Slide

  109. コルーチン
    イベントループ
    タスク

    View Slide

  110. コルーチン
    イベントループ
    タスク
    → やること

    View Slide

  111. コルーチン
    イベントループ
    タスク
    → やること
    → やること+実⾏状態をもつ
    (コルーチンの上位のやつ)

    View Slide

  112. コルーチン
    イベントループ
    タスク
    → やること
    → やること+実⾏状態をもつ
    (コルーチンの上位のやつ)
    → やることを管理するもの

    View Slide

  113. コルーチン
    イベントループ
    タスク
    → やること
    → やること+実⾏状態をもつ
    (コルーチンの上位のやつ)
    → やることを管理するもの

    View Slide

  114. レストラン

    View Slide

  115. 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
    asyncio

    View Slide

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

    View Slide

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

    View Slide

  118. asyncio
    注⽂を取 注⽂を取 注⽂を取

    View Slide

  119. asyncio
    イベントループ
    注⽂を取 注⽂を取 注⽂を取

    View Slide

  120. asyncio
    イベントループ
    (あくまでイメージ)
    注⽂を取 注⽂を取 注⽂を取

    View Slide

  121. コルーチン
    イベントループ
    タスク

    View Slide

  122. コルーチン
    イベントループ
    タスク

    View Slide

  123. •ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ
    コルーチン

    View Slide

  124. •ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ
    コルーチン
    •Co-routine ͱॻ͘

    View Slide

  125. •ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ
    コルーチン
    •Co-routine ͱॻ͘
    •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

    View Slide

  126. •ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ
    コルーチン
    •Co-routine ͱॻ͘
    •ؔ਺ͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await
    •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

    View Slide

  127. •ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ
    コルーチン
    •Co-routine ͱॻ͘
    •ؔ਺ͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await
    • asyncio Λ࢖͏্Ͱͷجຊͷ͖
    •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

    View Slide

  128. 関数を定義
    def customers_thinking_order():


    ... # ॲཧ

    View Slide

  129. def customers_long_thinking_order():


    ... # ࣌ؒͷ͔͔Δॲཧ
    コルーチンを定義
    async
    •async Λ͚ͭΔ͚ͩ
    •͍ͭ͜͸ίϧʔνϯؔ਺ʹͳΔ
    •def Ͱఆٛͨؔ͠਺ͱ΄΅มΘΒͳ͍

    View Slide

  130. def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    時間のかかる処理にawait
    async
    •࣌ؒͷ͔͔ΔॲཧʹawaitΛ͚ͭΔ
    •͔ͦ͜Βதஅͱ࠶։͢Δ
    •await Λ͚ͭΔ͜ͱ͕Ͱ͖Δͷ͸ɺίϧʔνϯ΍λεΫʢͳͲʣ

    View Slide

  131. 関数を実⾏
    def customers_long_thinking_order():


    time.sleep(10000)


    return “יͦ͹”
    >>> print(customers_long_thinking_order())
    יͦ͹
    # ௕ߟͷͷͪ

    View Slide

  132. def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    コルーチンを実⾏
    >>> print(customers_long_thinking_order())
    async

    View Slide

  133. def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    コルーチンを実⾏
    >>> print(customers_long_thinking_order())
    async


    at 0x10d949ec0>

    View Slide

  134. コルーチン
    イベントループ
    タスク

    View Slide

  135. asyncio
    イベントループ
    注⽂を取 注⽂を取 注⽂を取

    (あくまでイメージ)

    View Slide

  136. •C10K໰୊΁ͷճ౴
    •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ
    イベントループ

    View Slide

  137. •C10K໰୊΁ͷճ౴
    •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ
    •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά
    イベントループ

    View Slide

  138. •C10K໰୊΁ͷճ౴
    •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ
    •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ
    •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά
    イベントループ

    View Slide

  139. •C10K໰୊΁ͷճ౴
    •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ
    •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ
    •ͦ͜·Ͱҙࣝ͠ͳͯ͘΋ྑ͍ʢͦ͜ʹ͍Δ͜ͱ͸஌ͬͯͯʣ
    •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά
    イベントループ

    View Slide

  140. •C10K໰୊΁ͷճ౴
    •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ
    •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ
    •ͦ͜·Ͱҙࣝ͠ͳͯ͘΋ྑ͍ʢͦ͜ʹ͍Δ͜ͱ͸஌ͬͯͯʣ
    •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά
    イベントループ
    •asyncio ͷத֩Λͳ͢࢓૊Έ

    View Slide

  141. •Python 3.7 Ͱ௥Ճ͞Εͨ asyncio.run()
    イベントループ
    •ΠϕϯτϧʔϓΛ࡞Δ
    •λεΫ͕ऴΘͬͨΒ࡟আͯ͘͠ΕΔ
    •asyncio.run(corutine) Λड͚औΔ͜ͱ͕Ͱ͖Δ

    View Slide

  142. •Python 3.7 Ͱ௥Ճ͞Εͨ asyncio.run()
    イベントループ
    •ΠϕϯτϧʔϓΛ࡞Δ
    •λεΫ͕ऴΘͬͨΒ࡟আͯ͘͠ΕΔ
    •asyncio.run(corutine) Λड͚औΔ͜ͱ͕Ͱ͖Δ
    •loopΦϒδΣΫτ -> asyncio.get_running_loop() / run_until_complete()

    View Slide

  143. async def customers_long_thinking_order():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    イベントループを作る

    View Slide

  144. async def customers_long_thinking_order():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await customers_long_thinking_order()


    print(menu)

    View Slide

  145. イベントループを作る
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ

    View Slide

  146. イベントループを作る
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    # …௕ߟͷͷͪ
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  147. イベントループを作る
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    # …௕ߟͷͷͪ
    ͟Δͦ͹
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    # ίϧʔνϯͷ໭ΓΛड͚औͬͯprint

    View Slide

  148. イベントループを作る
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    # …௕ߟͷͷͪ
    ͟Δͦ͹
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    ऴΘͬͨΒΠϕϯτϧʔϓ͸


    ࡟আ

    View Slide

  149. 考え中のお客様 3⼈とも

    View Slide

  150. 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])

    View Slide

  151. 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 の動作を確認する

    View Slide

  152. 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())


    View Slide

  153. 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

    View Slide

  154. 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())


    View Slide

  155. 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

    View Slide

  156. 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

    View Slide

  157. コルーチン
    イベントループ
    タスク

    View Slide

  158. •TaskΦϒδΣΫτ
    •ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛ΋ͭ
    •࡞Δํ๏͸େ͖͘2ͭ
    •Python3.7 Ͱ௥Ճ͞Εͨ asyncio.create_task()
    •Πϕϯτϧʔϓʹొ࿥͢Δ
    •ฒྻ࣮ߦΛॿ͚Δ gather()
    タスク

    View Slide

  159. 初めてのタスク
    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())


    View Slide

  160. 初めてのタスク
    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, “͟Δͦ͹”

    View Slide

  161. 初めてのタスク
    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())


    View Slide

  162. 初めてのタスク
    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())


    実⾏してみましょう

    View Slide

  163. 初めてのタスク
    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

    View Slide

  164. 初めてのタスク
    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())


    実⾏してみましょう

    View Slide

  165. 初めてのタスク
    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

    View Slide

  166. 初めてのタスク
    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

    View Slide

  167. 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())

    View Slide

  168. 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

    View Slide

  169. 考え中のお客様

    View Slide

  170. 考え中のお客様
    検索しないと決
    められない

    View Slide

  171. 考え中のお客様
    検索しないと決
    められない
    3⼈とも

    View Slide

  172. 考え中のお客様
    検索しないと決
    められない
    3⼈とも
    asyncio
    ⾮同期IO

    View Slide

  173. 考え中のお客様が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)


    View Slide

  174. 考え中のお客様が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

    View Slide

  175. 考え中のお客様が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

    View Slide

  176. 考え中のお客様が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

    View Slide

  177. asyncio
    イベントループ
    注⽂を取 注⽂を取 注⽂を取

    (あくまでイメージ)

    View Slide

  178. 考え中のお客様が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)

    View Slide

  179. 考え中のお客様が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
    ͪΐͬͱ଴ͬͯͶ
    ͪΐͬͱ଴ͬͯͶ
    ͪΐͬͱ଴ͬͯͶ
    < 3FTQPOTF0,> b͟Δͦ͹`

    UJNF

    View Slide

  180. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ

    View Slide

  181. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

    View Slide

  182. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ


    ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

    View Slide

  183. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ


    ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ
    登録してあるタスクを
    awaitのタイミングで切
    り替える。ただし
    asyncio対応が必要。
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

    View Slide

  184. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    create_task(coro) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ
    async def hoge()


    await λεΫ ·ͨ͸ ίϧʔνϯ
    asynio.run(ίϧʔνϯ)
    ༨ྗ͕͋Ε͹ɺget_running_loop()ͬͯͷ΋ 🙏

    View Slide

  185. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    create_task(coro) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ
    async def hoge()


    await λεΫ ·ͨ͸ ίϧʔνϯ
    asynio.run(ίϧʔνϯ)
    ༨ྗ͕͋Ε͹ɺget_running_loop()ͬͯͷ΋ 🙏
    まずはこれを抑えましょう

    View Slide

  186. わたしたちはいくつかの
    武器を⼿に⼊れました。

    View Slide

  187. 注⽂を取る - 料理を 注⽂を取る - 料理を 注⽂を取る - 料理を
    並⾏処理

    View Slide

  188. 注⽂を取る 注⽂を取る 注⽂を取る
    並⾏処理 ⾮同期IO

    View Slide

  189. 注⽂を取る 注⽂を取る 注⽂を取る
    並⾏処理
    ⾮同期IO

    asyncio

    View Slide

  190. 注⽂を取る 注⽂を取る 注⽂を取る
    並⾏処理
    ⾮同期IO

    asyncio
    ちょっとわがまま

    View Slide

  191. View Slide

  192. 本⽇のおしながき
    •Django 3.1 - Async View
    •Django 3.x or 4? - Async ORM
    •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ

    View Slide

  193. Django 3.2 ASGI対応
    Junya Fukuda
    DjangoCongress JP 2021
    -こわくない asyncio 基礎とasync viewの使い所

    View Slide

  194. Django 3.2 ASGI対応
    Junya Fukuda
    DjangoCongress JP 2021
    -こわくない asyncio 基礎とasync viewの使い所

    View Slide

  195. Django Async View ͷ࢖͍ॴ
    •ASGIରԠͱasync view

    View Slide

  196. Django Async View ͷ࢖͍ॴ
    •ASGIରԠͱasync view
    •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ

    View Slide

  197. Django Async View ͷ࢖͍ॴ
    •ASGIରԠͱasync view
    •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ

    View Slide

  198. Django Async View ͷ࢖͍ॴ
    •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ
    •ASGIରԠͱasync view
    •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ

    View Slide

  199. Django Async View ͷ࢖͍ॴ
    •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ
    •ྫ͑͹APIͷϦΫΤετ
    •ྫ͑͹IoTσόΠεͱͷMQTT
    •ASGIରԠͱasync view
    •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ

    View Slide

  200. Django Async View ͷ࢖͍ॴ
    •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ
    •ྫ͑͹APIͷϦΫΤετ
    •ྫ͑͹IoTσόΠεͱͷMQTT
    •ASGIରԠͱasync view
    •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ
    •DjangoΛར༻͍ͨ͠৔߹

    View Slide

  201. 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)


    View Slide

  202. 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
    ͸͠ͳ͍ͷʁ🤔

    View Slide

  203. Django Async View の使い所
    •Έͳ͞Μ΋͏ͯ͠·͢ɻ

    View Slide

  204. Django Async View の使い所
    •Έͳ͞Μ΋͏ͯ͠·͢ɻ
    •஌Βͣ஌Βͣͷ͏ͪʹɻ

    View Slide

  205. Django Async View の使い所
    •Έͳ͞Μ΋͏ͯ͠·͢ɻ
    •஌Βͣ஌Βͣͷ͏ͪʹɻ
    •ASGI Django ͬͯͲ͏΍࣮ͬͯߦ͠·͔͢ʁ

    View Slide

  206. Django Async View の使い所
    •Έͳ͞Μ΋͏ͯ͠·͢ɻ
    •஌Βͣ஌Βͣͷ͏ͪʹɻ
    •ASGI Django ͬͯͲ͏΍࣮ͬͯߦ͠·͔͢ʁ
    $ uvicorn hello_async_world.asgi:application

    View Slide

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

    View Slide

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

    View Slide

  209. Django Async View の使い所
    •ඇಉظͳॲཧΛߦ͍͍ͨ৔߹ʹ͸ɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ

    View Slide

  210. Django Async View の使い所
    •ඇಉظͳॲཧΛߦ͍͍ͨ৔߹ʹ͸ɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ
    •ͨͩඇಉظͳॲཧͷதʹ΋ɺಉظͷॲཧʢasyncioରԠ͍ͯ͠ͳ͍ʣ͕͍Δ

    View Slide

  211. Django Async View の使い所
    •ඇಉظͳॲཧΛߦ͍͍ͨ৔߹ʹ͸ɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ
    •ͨͩඇಉظͳॲཧͷதʹ΋ɺಉظͷॲཧʢasyncioରԠ͍ͯ͠ͳ͍ʣ͕͍Δ
    •ಉظॲཧʹ͸ɺDjango͕༻ҙͯ͘͠Ε͍ͯΔಉظॲཧˠඇಉظॲཧʹ͢Δ
    •sync_to_async()

    View Slide

  212. Django Async View の使い所
    •sync_to_async()
    ಉظؔ਺Λड͚औΓɺͦΕΛϥοϓͯ͠ඇಉظؔ਺Λฦ͠·͢ɻ


    ௚઀ϥούʔ·ͨ͸σίϨʔλͱͯ͠࢖༻Ͱ͖·͢ɻ

    View Slide

  213. 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

    View Slide

  214. Django Async View の使い所
    •sync_to_async()
    asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ࿥͢Δ͜ͱ͕Ͱ͖·͢ɻ


    ʢDjangoʹݶͬͨ࿩Ͱ͸ͳ͘ʣ

    View Slide

  215. Django Async View の使い所
    •sync_to_async()
    asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ࿥͢Δ͜ͱ͕Ͱ͖·͢ɻ


    ʢDjangoʹݶͬͨ࿩Ͱ͸ͳ͘ʣ
    concurrent.futures Ϟδϡʔϧ
    ʢthreading ͱ multiprocessing Λ༰қʹ࢖͑Δඪ४ϥΠϒϥϦʣ

    View Slide

  216. Django Async View の使い所
    •sync_to_async()
    asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ࿥͢Δ͜ͱ͕Ͱ͖·͢ɻ


    ʢDjangoʹݶͬͨ࿩Ͱ͸ͳ͘ʣ
    concurrent.futures Ϟδϡʔϧ
    ʢthreading ͱ multiprocessing Λ༰қʹ࢖͑Δඪ४ϥΠϒϥϦʣ
    ͜ΕͰඇಉظʹͰ͖Δ…ʹ͸Ͱ͖·͕͢ɺ


    ࣮ߦʹίετ͕͔͔Γ଎౓ʹӨڹ͕ଟগ͋Γ·͢ɻ

    View Slide

  217. Django Async View の使い所
    •ASGIରԠͱasync view

    View Slide

  218. Django Async View の使い所
    •ASGIରԠͱasync view
    •͜ΕʹΑͬͯɺDjangoͰ΋asyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ

    View Slide

  219. Django Async View の使い所
    •ASGIରԠͱasync view
    •͜ΕʹΑͬͯɺDjangoͰ΋asyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ
    •ಉظॲཧ΋ concurrent.futures Λ࢖ͬͨϥοϓ͕Մೳ

    View Slide

  220. Django Async View の使い所
    •ASGIରԠͱasync view
    •͜ΕʹΑͬͯɺDjangoͰ΋asyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ
    •ಉظॲཧ΋ concurrent.futures Λ࢖ͬͨϥοϓ͕Մೳ
    •·ͩ࢒͍ͬͯΔಉظॲཧ

    View Slide

  221. Django Async View の使い所
    •ASGIରԠͱasync view
    •͜ΕʹΑͬͯɺDjangoͰ΋asyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ
    •ಉظॲཧ΋ concurrent.futures Λ࢖ͬͨϥοϓ͕Մೳ
    •·ͩ࢒͍ͬͯΔಉظॲཧ
    •ͦ͏ɻ࠷ޙͷࡆɻDjangoͷORM͕࢒͍ͬͯΔɻʢasyncio ະରԠʣ

    View Slide

  222. View Slide

  223. Async ORM

    View Slide

  224. Node.jsの作成者であるRyan Dahlは尋ねました。

    View Slide

  225. Node.jsの作成者であるRyan Dahlは尋ねました。
    「データベースにクエリを実⾏している間、
    ソフトウェアは何をしているのですか?」

    View Slide

  226. Node.jsの作成者であるRyan Dahlは尋ねました。
    「データベースにクエリを実⾏している間、
    ソフトウェアは何をしているのですか?」
    https://www.youtube.com/watch?v=ztspvPYybIY
    もちろん、答えは何もありませんでした。
    データベースが応答するのを待っていました。

    View Slide

  227. Django ORM
    •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM

    View Slide

  228. Django ORM
    •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM
    •ORM͸asyncioରԠ͍ͯ͠ͳ͍

    View Slide

  229. Django ORM
    •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM
    •ඇಉظIOͷར఺Λ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ
    •ORM͸asyncioରԠ͍ͯ͠ͳ͍

    View Slide

  230. Django ORM
    •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM
    •ඇಉظIOͷར఺Λ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ
    •΋ͪΖΜσʔλϕʔε΁ͷΞΫηε΋༗ޮ
    •ORM͸asyncioରԠ͍ͯ͠ͳ͍

    View Slide

  231. Django ORM
    •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM
    •ඇಉظIOͷར఺Λ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ
    •΋ͪΖΜσʔλϕʔε΁ͷΞΫηε΋༗ޮ
    •ࠓ͞Θ͍ͬͯΔΞϓϦέʔγϣϯΛࢥ͍ग़͍ͯͩ͘͠͞ɻDB͕ඇಉظʹͳͬͨΒ…
    •ORM͸asyncioରԠ͍ͯ͠ͳ͍

    View Slide

  232. Async ORM
    •Async ORM ΁ͷಓ
    •PyConline AU 2020 "Taking Django's ORM Async”
    •Django ίΞ developer Andrew Godwin ͞Μ

    View Slide

  233. Async ORM
    •Async ORM ΁ͷಓ
    •APIͷσβΠϯ͕ॏཁͩ
    •ͨͩɺasync DBAPI ͸·ͩͳ͍…
    •՝୊͸͋Δ
    •Model API / ΫΤϦ / DBΞμϓλʔ ͱରԠ͍ͯ͘͠ܭը

    View Slide

  234. Async ORM
    •Async ORM ΁ͷಓ
    •ඇಉظΛՄೳͳݶΓ࠷ߴͷ΋ͷʹ͢Δ͜ͱΛ͓఻͑͠·͢ 🎉🎉🎉
    •҆શͳඇಉظϓϩάϥϛϯά
    •͢΂͕ͯඇಉظͰɺඇಉظͰΤϥʔ͕ىͤ͜ͳ͍ੈքΛ࣮ݱ

    View Slide

  235. Async ORM
    •۩ମతͳόʔδϣϯ͸…΋͏গ͔͔͠Γͦ͏Ͱ͢
    •ָ͠ΈͰ͢Ͷ˒
    IUUQTGPSVNEKBOHPQSPKFDUDPNUBTZODISPOPVTPSN

    View Slide

  236. まとめ
    •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔

    •Django async view - ಉظͱඇಉظ߹Θͤͯ


    IOό΢ϯυͳॲཧΛத৺ʹ…
    •Async ORM - ָ͠ΈͰ͢Ͷʂ


    ʢPyhtonͰ͸ asyncio ରԠͷORM΍Ξμϓλʔ΋͢Ͱʹ͍͔ͭ͋͘Γ·͢ɻʣ


    ·ͨɺDjango͸OSSͰ͢ɻϦϙδτϦΛͷ͍ͧͯΈΔͷ΋ྑ͍͔΋͠Ε·ͤΜ 👀
    IUUQTHJUIVCDPNEKBOHPEKBOHP

    View Slide

  237. •ίϧʔνϯ͸ා͘ͳ͍ - 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

    View Slide

  238. ご静聴ありがとうございました 👋

    View Slide