Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Django 3.2 ASGI対応 - こわくない asyncio 基礎とasync view...
Search
Junya Fukuda
July 03, 2021
Programming
1
2.5k
Django 3.2 ASGI対応 - こわくない asyncio 基礎とasync viewの使い所
DjangoCongressJP 2021 の登壇資料です。
Junya Fukuda
July 03, 2021
Tweet
Share
More Decks by Junya Fukuda
See All by Junya Fukuda
プロダクションでのPython非同期ユースケース - Trio/Trio-Utilを中心に
jrfk
2
100
Event-Driven asyncio: A Case Study of Trio's API(PyCon US 2024)
jrfk
1
120
EuroPython 2023体験記 - 非英語話者の海外登壇@みんなのPython勉強会#98
jrfk
0
180
Asyncio Evolved: Enhanced Exception Handling with TaskGroup in Python 3.11(PyConTW 2023)
jrfk
0
35
Asyncio Evolved: Enhanced Exception Handling with TaskGroup in Python 3.11(EuroPython 2023)
jrfk
3
1.2k
Django 4.1のAsynchronous
jrfk
1
2.2k
New in Python 3.11: asyncio.TaskGroup and “Hello-ish World” of Asyncio
jrfk
0
470
Python3.11新機能asyncio.TaskGroup()と2022年asyncioの"Hello-ish world"
jrfk
3
3.7k
こわくないasyncio基礎と非同期IO - 動くコードを添えて
jrfk
0
760
Other Decks in Programming
See All in Programming
ファーストペンギンBot @Qiita Hackathon 2024 予選
dyson_web
0
220
データサイエンスのフルサイクル開発を実現する機械学習パイプライン
xcnkx
2
500
フロントエンドの現在地とこれから
koba04
10
4.5k
◯◯エンジニアになった理由
gessy0129
PRO
0
650
UnJSで簡単に始めるCLIツール開発 / cli-tool-development-with-unjs
aoseyuu
2
260
文化が生産性を作る
jimpei
3
560
Интеграционное тестирование: как приручить хаос
lamodatech
0
560
M5Stack に色々な M5ユニットをつないで扱う為の新たなアプローチ
gob
0
210
Beyond Laravel Octane - Hyperf for Laravel Artisans
albertcht
1
130
全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例
blueswen
1
380
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
1.2k
RemixとCloudflare Stack におけるFile Upload
ossamoon
1
130
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
519
39k
For a Future-Friendly Web
brad_frost
174
9.3k
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.2k
Into the Great Unknown - MozCon
thekraken
30
1.4k
Happy Clients
brianwarren
97
6.7k
4 Signs Your Business is Dying
shpigford
180
21k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
45
2k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.3k
Agile that works and the tools we love
rasmusluckow
327
21k
Statistics for Hackers
jakevdp
796
220k
A Philosophy of Restraint
colly
203
16k
Transcript
Django 3.2 ASGI対応 Junya Fukuda DjangoCongress JP 2021 -こわくない asyncio
基礎とasync viewの使い所
•ా ൏ʢJunya Fukudaʣʢ@JunyaFffʣ •גࣜձࣾຊγεςϜٕݚʢJSLʣॴଐ ݝͷձࣾ •WebΤϯδχΞ •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ •Effective
Python ͷಡॻձͬͯ·͢ 📚 •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε •ຊ͖ʹѪ͞ΕΔαʔϏεΛࢦͯ͠ʢݹຊങऔɾൢചʣ ΪʔΫϥϘಡॻձ
こんにちは⻑野!
ハイブリット開催ですね🎉 (オンライン&オフライン)
ハイブリット開催ですね🎉 (オンライン&オフライン) わたしは初めてのオフラインです。
オフラインのひと〜👋
オンラインのひと〜👋
🙌
Django 3.2
•Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress JP Django 3.2 •Django 3 ͷۄͷ1ͭ •Django
3.0 - ASGIରԠ •Django 3.1 - Async View, ϛυϧΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ
•Django 3 ͕ग़͔ͯΒͷॳΊͯͷDjangoCongress Django 3.2 •Django 3 ͷۄͷ1ͭ •Django 3.0
- ASGIରԠ •Django 3.1 - Async View, ϛυϧΣΞ, ςετΫϥΠΞϯτ ͷαϙʔτ
•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
Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ༷ って?
Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ༷ •WSGIͷਫ਼ਆతޙܧ って?
Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn uWSGI ⁶
Django Flask, Pyramid って?
Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn uWSGI ⁶
Django Flask, Pyramid •Uvicorn Hypercorn ⁶ Django FastAPI, Starlette って?
Django 3.0 - ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn uWSGI ⁶
Django Flask, Pyramid •Uvicorn Hypercorn ⁶ Django FastAPI, Starlette •WSGIͱASGIɺͳʹ͕ҧ͏ͷ͔ って? WSGI
WSGI
WSGI Web Server Gateway Interface
WSGI Web Server Gateway Interface ASGI
WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface
WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface
WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface
⾮同期
WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface
⾮同期 ASGI= asyncio
•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
•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ରԠ
本⽇のおしながき •Django 3.1 - Async View ͷ͍ॴ •Django 3.x or
4? - Async ORM •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ
•asyncio͜Θ͍ͳ͋… •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ •Django ORM ͍͚Δͷʁʁ
•asyncio͜Θ͍ͳ͋… •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ •Django ORM ͍͚Δͷʁʁ •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ
👋
•asyncio͜Θ͍ͳ͋… •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ •Django ORM ͍͚Δͷʁʁ •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ
👋 •Django async view ͬͯͦ͏͍͏ͱ͖Ͷ 🙌
•asyncio͜Θ͍ͳ͋… •Django async view ͬͯͳʹ͕͓͍͍͠ͷʁ •Django ORM ͍͚Δͷʁʁ •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ
👋 •Django async view ͬͯͦ͏͍͏ͱ͖Ͷ 🙌 •Django async ORM ͨͷ͠Έͩͳ͋ʙ ✊
すべてはasync/awaitから始まった
> IUUQT fl PSJNPOEEFWCMPHBSUJDMFTJOUSPEVDUJPOUPBTHJBTZODQZUIPOXFC すべてはasync/awaitから始まった
asyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ asyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
asyncio めっちゃこわい
•͜Θ͔ͬͨ asyncio めっちゃこわい
•͜Θ͔ͬͨ •ίϧʔνϯා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ •Using Asyncio in
Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍
•asyncio ڊେ 対象はアプリーケーション開発者
•asyncio ڊେ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ
•asyncio ڊେ •Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ
•asyncio ڊେ •ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ
•asyncio ڊେ •ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ •ΞϓϦέʔγϣϯ։ൃऀ͚Λରʹͨ͠༰Ͱ͢
•asyncio ڊେ •ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ •ΞϓϦέʔγϣϯ։ൃऀ͚Λରʹͨ͠asyncio •લఏࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ
•asyncio ڊେ •ϑϨʔϜϫʔΫϥΠϒϥϦ։ൃऀ͚ͷػೳͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠ΞϓϦέʔγϣϯ։ൃऀ 対象はアプリーケーション開発者 •ެࣜυΩϡϝϯτߴϨϕϧ APIͱϨϕϧAPIʹ͔ΕͯΔ •ΞϓϦέʔγϣϯ։ൃऀ͚Λରʹͨ͠asyncio •લఏࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic
⾔葉を完全に理解する
IUUQTEPDTQZUIPOPSHKBMJCSBSZBTZODJPIUNM
前提知識 並⾏処理
前提知識 並⾏処理 並列処理
前提知識 並⾏処理 並列処理 順次処理
前提知識 並⾏処理 並列処理 順次処理 タスクの処理
並⾏処理 並列処理 順次処理
並⾏処理 並列処理 順次処理
並⾏処理 並列処理 順次処理
並⾏処理 並列処理 順次処理 通常の関数を呼び出していく処理
並⾏処理 並列処理 順次処理 通常の関数を呼び出していく処理 multiprocessingモジュール
並⾏処理 並列処理 順次処理 通常の関数を呼び出していく処理 multiprocessingモジュール threadingモジュール asyncioモジュール
ちょっとわかりにくいので レストラン🍽に例えます
レストラン
レストラン どんなタスクが あるでしょうか
注⽂をとる
料理を作る 注⽂をとる
料理を作る 注⽂をとる 料理を運ぶ
順次処理
順次処理 注⽂を取る - 料理を作る - 料理を運ぶ
順次処理 注⽂を取る - 料理を作る - 料理を運ぶ 完了してから次のタスク
並列処理
並列処理 注⽂を取る 料理を作る 料理を運ぶ
並列処理 注⽂を取る 料理を作る 料理を運ぶ 複数のタスクを同時に着⼿する
並⾏処理
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ 同じ⼈
並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔
asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた
asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた お客様
asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた お客様 ←注⽂
asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち
asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、
外部のお客様、から 注⽂という ⼊⼒を待つ状態
asyncio どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、 外部のお客様、から 注⽂という ⼊⼒を待つ状態
a どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、 外部のお客様、から 注⽂という ⼊⼒を待つ状態
⾮同期IO syncio
a sync io
a sync io ⼊⼒
a sync io 同期 ⼊⼒
a sync io しない 同期 ⼊⼒
asyncio ⾮同期IO
asyncio ⾮同期IO
asyncio ⾮同期IO
•Python 3.4 Ͱ Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظแදه
•Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌRFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮ aioquic γϯάϧεϨου ฒߦॲཧ ඇಉظ IO
ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO
ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO
ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO ϫϯΦϖ
ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO ϫϯΦϖ 外部のお客様、から 注⽂という ⼊⼒を待たないで他のことする
asyncio
asyncio🌷
asyncio で 覚えておくことは3つ asyncio
イベントループ
コルーチン イベントループ
コルーチン イベントループ タスク
コルーチン イベントループ タスク → やること
コルーチン イベントループ タスク → やること → やること+実⾏状態をもつ (コルーチンの上位のやつ)
コルーチン イベントループ タスク → やること → やること+実⾏状態をもつ (コルーチンの上位のやつ) → やることを管理するもの
コルーチン イベントループ タスク → やること → やること+実⾏状態をもつ (コルーチンの上位のやつ) → やることを管理するもの
レストラン
注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
注⽂を取る - 料理を作る - 料理を運ぶ asyncio
注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ
注⽂を取る - 料理を作る - 料理を運ぶ asyncio コルーチンやタスク
asyncio 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る -
料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ コルーチンやタスク
asyncio 注⽂を取 注⽂を取 注⽂を取 コ
asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ
asyncio イベントループ (あくまでイメージ) 注⽂を取 注⽂を取 注⽂を取 コ
コルーチン イベントループ タスク
コルーチン イベントループ タスク
•ίϧʔνϯͱɺϧʔνϯʢ͍ҙຯͰͷؔʣͷҰछ コルーチン
•ίϧʔνϯͱɺϧʔνϯʢ͍ҙຯͰͷؔʣͷҰछ コルーチン •Co-routine ͱॻ͘
•ίϧʔνϯͱɺϧʔνϯʢ͍ҙຯͰͷؔʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ
•ίϧʔνϯͱɺϧʔνϯʢ͍ҙຯͰͷؔʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ؔͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ
•ίϧʔνϯͱɺϧʔνϯʢ͍ҙຯͰͷؔʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ؔͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await •
asyncio Λ͏্Ͱͷجຊͷ͖ •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ
関数を定義 def customers_thinking_order(): ... # ॲཧ
def customers_long_thinking_order(): ... # ࣌ؒͷ͔͔Δॲཧ コルーチンを定義 async •async Λ͚ͭΔ͚ͩ •͍ͭ͜ίϧʔνϯؔʹͳΔ
•def Ͱఆٛͨؔ͠ͱ΄΅มΘΒͳ͍
def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ” 時間のかかる処理にawait async •࣌ؒͷ͔͔ΔॲཧʹawaitΛ͚ͭΔ •͔ͦ͜Βதஅͱ࠶։͢Δ
•await Λ͚ͭΔ͜ͱ͕Ͱ͖ΔͷɺίϧʔνϯλεΫʢͳͲʣ
関数を実⾏ def customers_long_thinking_order(): time.sleep(10000) return “יͦ” >>> print(customers_long_thinking_order()) יͦ #
ߟͷͷͪ
def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ” コルーチンを実⾏ >>> print(customers_long_thinking_order()) async
def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ” コルーチンを実⾏ >>> print(customers_long_thinking_order()) async
<coroutine object customers_long_thinking_order at 0x10d949ec0>
コルーチン イベントループ タスク
asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ (あくまでイメージ)
•C10Kͷճ •libuv(nodejs)ͷத֩Λͳ͢Έ イベントループ
•C10Kͷճ •libuv(nodejs)ͷத֩Λͳ͢Έ •ίϧʔνϯλεΫΛεέδϡʔϦϯά イベントループ
•C10Kͷճ •libuv(nodejs)ͷத֩Λͳ͢Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ •ίϧʔνϯλεΫΛεέδϡʔϦϯά イベントループ
•C10Kͷճ •libuv(nodejs)ͷத֩Λͳ͢Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ •ͦ͜·Ͱҙࣝ͠ͳͯ͘ྑ͍ʢͦ͜ʹ͍Δ͜ͱͬͯͯʣ •ίϧʔνϯλεΫΛεέδϡʔϦϯά イベントループ
•C10Kͷճ •libuv(nodejs)ͷத֩Λͳ͢Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷΈ •ͦ͜·Ͱҙࣝ͠ͳͯ͘ྑ͍ʢͦ͜ʹ͍Δ͜ͱͬͯͯʣ •ίϧʔνϯλεΫΛεέδϡʔϦϯά イベントループ •asyncio ͷத֩Λͳ͢Έ
•Python 3.7 ͰՃ͞Εͨ asyncio.run() イベントループ •ΠϕϯτϧʔϓΛ࡞Δ •λεΫ͕ऴΘͬͨΒআͯ͘͠ΕΔ •asyncio.run(corutine) Λड͚औΔ͜ͱ͕Ͱ͖Δ
•Python 3.7 ͰՃ͞Εͨ asyncio.run() イベントループ •ΠϕϯτϧʔϓΛ࡞Δ •λεΫ͕ऴΘͬͨΒআͯ͘͠ΕΔ •asyncio.run(corutine) Λड͚औΔ͜ͱ͕Ͱ͖Δ •loopΦϒδΣΫτ
-> asyncio.get_running_loop() / run_until_complete()
async def customers_long_thinking_order(): print(“ͪΐͬͱͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ” イベントループを作る
async def customers_long_thinking_order(): print(“ͪΐͬͱͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ” イベントループを作る async
def order(): print(“͝จʁ”) menu = await customers_long_thinking_order() print(menu)
イベントループを作る asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ͝จʁ ͪΐͬͱͬͯͶ
イベントループを作る ͝จʁ ͪΐͬͱͬͯͶ # …ߟͷͷͪ asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
イベントループを作る ͝จʁ ͪΐͬͱͬͯͶ # …ߟͷͷͪ ͟Δͦ asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ #
ίϧʔνϯͷΓΛड͚औͬͯprint
イベントループを作る ͝จʁ ͪΐͬͱͬͯͶ # …ߟͷͷͪ ͟Δͦ asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ↑
ऴΘͬͨΒΠϕϯτϧʔϓ আ
考え中のお客様 3⼈とも
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])
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 の動作を確認する
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())
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
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())
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
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
コルーチン イベントループ タスク
•TaskΦϒδΣΫτ •ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛͭ •࡞Δํ๏େ͖͘2ͭ •Python3.7 ͰՃ͞Εͨ asyncio.create_task() •Πϕϯτϧʔϓʹొ͢Δ •ฒྻ࣮ߦΛॿ͚Δ gather() タスク
初めてのタスク 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())
初めてのタスク 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, “͟Δͦ”
初めてのタスク 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())
初めてのタスク 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()) 実⾏してみましょう
初めてのタスク 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
初めてのタスク 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()) 実⾏してみましょう
初めてのタスク 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
初めてのタスク 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
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())
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
考え中のお客様
考え中のお客様 検索しないと決 められない
考え中のお客様 検索しないと決 められない 3⼈とも
考え中のお客様 検索しないと決 められない 3⼈とも asyncio ⾮同期IO
考え中のお客様が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)
考え中のお客様が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
考え中のお客様が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
考え中のお客様が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
asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ (あくまでイメージ)
考え中のお客様が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)
考え中のお客様が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
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ ؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ͓ͯ͘͠ͱ ྑ͖ʹܭΒͬͯΓସ͑ͯ͘ΕΔɻ ؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ͓ͯ͘͠ͱ ྑ͖ʹܭΒͬͯΓସ͑ͯ͘ΕΔɻ 登録してあるタスクを awaitのタイミングで切 り替える。ただし asyncio対応が必要。
ؔʹ async Λ͚ͭΔ͚ͩ ؊await
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(coro) - Πϕϯτϧʔϓʹొ gather(λεΫ ·ͨ ίϧʔνϯ)
- ·ͱΊͯ݁ՌΛड͚औΕΔ async def hoge() await λεΫ ·ͨ ίϧʔνϯ asynio.run(ίϧʔνϯ) ༨ྗ͕͋Εɺget_running_loop()ͬͯͷ 🙏
ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(coro) - Πϕϯτϧʔϓʹొ gather(λεΫ ·ͨ ίϧʔνϯ)
- ·ͱΊͯ݁ՌΛड͚औΕΔ async def hoge() await λεΫ ·ͨ ίϧʔνϯ asynio.run(ίϧʔνϯ) ༨ྗ͕͋Εɺget_running_loop()ͬͯͷ 🙏 まずはこれを抑えましょう
わたしたちはいくつかの 武器を⼿に⼊れました。
注⽂を取る - 料理を 注⽂を取る - 料理を 注⽂を取る - 料理を 並⾏処理
注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO
注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO コ asyncio
注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO コ asyncio ちょっとわがまま
None
本⽇のおしながき •Django 3.1 - Async View •Django 3.x or 4?
- Async ORM •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ
Django 3.2 ASGI対応 Junya Fukuda DjangoCongress JP 2021 -こわくない asyncio
基礎とasync viewの使い所
Django 3.2 ASGI対応 Junya Fukuda DjangoCongress JP 2021 -こわくない asyncio
基礎とasync viewの使い所
Django Async View ͷ͍ॴ •ASGIରԠͱasync view
Django Async View ͷ͍ॴ •ASGIରԠͱasync view •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ
Django Async View ͷ͍ॴ •ASGIରԠͱasync view •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ
Django Async View ͷ͍ॴ •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ •ASGIରԠͱasync view •asyncio ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ
Django Async View ͷ͍ॴ •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ •ྫ͑APIͷϦΫΤετ •ྫ͑IoTσόΠεͱͷMQTT •ASGIରԠͱasync view •asyncio
ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ
Django Async View ͷ͍ॴ •IOͷൃੜ͢ΔॲཧͰޮՌΛൃش͢Δ •ྫ͑APIͷϦΫΤετ •ྫ͑IoTσόΠεͱͷMQTT •ASGIରԠͱasync view •asyncio
ඇಉظIO ͷྑ͖ͱ͜ΖΛڗडͰ͖Δ •DjangoΛར༻͍ͨ͠߹
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)
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 ͠ͳ͍ͷʁ🤔
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ •ΒͣΒͣͷ͏ͪʹɻ
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ •ΒͣΒͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏࣮ͬͯߦ͠·͔͢ʁ
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ •ΒͣΒͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏࣮ͬͯߦ͠·͔͢ʁ $
uvicorn hello_async_world.asgi:application
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ •ΒͣΒͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏࣮ͬͯߦ͠·͔͢ʁ $
uvicorn hello_async_world.asgi:application •ASGIͰɺPythonͷWebαʔόͱPythonͷWeb FWΛܨ͍ͰΔ
Django Async View の使い所 •Έͳ͞Μ͏ͯ͠·͢ɻ •ΒͣΒͣͷ͏ͪʹɻ •ASGI Django ͬͯͲ͏࣮ͬͯߦ͠·͔͢ʁ $
uvicorn hello_async_world.asgi:application •ASGIͰɺPythonͷWebαʔόͱPythonͷWeb FWΛܨ͍ͰΔ •ASGIαʔόଆͰΠϕϯτϧʔϓΛ࣮ߦ͍ͯ͠Δ
Django Async View の使い所 •ඇಉظͳॲཧΛߦ͍͍ͨ߹ʹɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ
Django Async View の使い所 •ඇಉظͳॲཧΛߦ͍͍ͨ߹ʹɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ •ͨͩඇಉظͳॲཧͷதʹɺಉظͷॲཧʢasyncioରԠ͍ͯ͠ͳ͍ʣ͕͍Δ
Django Async View の使い所 •ඇಉظͳॲཧΛߦ͍͍ͨ߹ʹɺASGIΞϓϦͱ࣮ͯ͠ߦ͢Δ •ͨͩඇಉظͳॲཧͷதʹɺಉظͷॲཧʢasyncioରԠ͍ͯ͠ͳ͍ʣ͕͍Δ •ಉظॲཧʹɺDjango͕༻ҙͯ͘͠Ε͍ͯΔಉظॲཧˠඇಉظॲཧʹ͢Δ •sync_to_async()
Django Async View の使い所 •sync_to_async() ಉظؔΛड͚औΓɺͦΕΛϥοϓͯ͠ඇಉظؔΛฦ͠·͢ɻ ϥούʔ·ͨσίϨʔλͱͯ͠༻Ͱ͖·͢ɻ
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
Django Async View の使い所 •sync_to_async() asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ͢Δ͜ͱ͕Ͱ͖·͢ɻ ʢDjangoʹݶͬͨͰͳ͘ʣ
Django Async View の使い所 •sync_to_async() asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ͢Δ͜ͱ͕Ͱ͖·͢ɻ ʢDjangoʹݶͬͨͰͳ͘ʣ concurrent.futures Ϟδϡʔϧ ʢthreading
ͱ multiprocessing Λ༰қʹ͑Δඪ४ϥΠϒϥϦʣ
Django Async View の使い所 •sync_to_async() asyncioରԠ͍ͯ͠ͳ͍ಉظॲཧΛΠϕϯτϧʔϓʹొ͢Δ͜ͱ͕Ͱ͖·͢ɻ ʢDjangoʹݶͬͨͰͳ͘ʣ concurrent.futures Ϟδϡʔϧ ʢthreading
ͱ multiprocessing Λ༰қʹ͑Δඪ४ϥΠϒϥϦʣ ͜ΕͰඇಉظʹͰ͖Δ…ʹͰ͖·͕͢ɺ ࣮ߦʹίετ͕͔͔ΓʹӨڹ͕ଟগ͋Γ·͢ɻ
Django Async View の使い所 •ASGIରԠͱasync view
Django Async View の使い所 •ASGIରԠͱasync view •͜ΕʹΑͬͯɺDjangoͰasyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ
Django Async View の使い所 •ASGIରԠͱasync view •͜ΕʹΑͬͯɺDjangoͰasyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ •ಉظॲཧ concurrent.futures Λͬͨϥοϓ͕Մೳ
Django Async View の使い所 •ASGIରԠͱasync view •͜ΕʹΑͬͯɺDjangoͰasyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ •ಉظॲཧ concurrent.futures Λͬͨϥοϓ͕Մೳ
•·͍ͩͬͯΔಉظॲཧ
Django Async View の使い所 •ASGIରԠͱasync view •͜ΕʹΑͬͯɺDjangoͰasyncioʹΑΔඇಉظIO/ฒߦॲཧͷԸܙ •ಉظॲཧ concurrent.futures Λͬͨϥοϓ͕Մೳ
•·͍ͩͬͯΔಉظॲཧ •ͦ͏ɻ࠷ޙͷࡆɻDjangoͷORM͕͍ͬͯΔɻʢasyncio ະରԠʣ
None
Async ORM
Node.jsの作成者であるRyan Dahlは尋ねました。
Node.jsの作成者であるRyan Dahlは尋ねました。 「データベースにクエリを実⾏している間、 ソフトウェアは何をしているのですか?」
Node.jsの作成者であるRyan Dahlは尋ねました。 「データベースにクエリを実⾏している間、 ソフトウェアは何をしているのですか?」 https://www.youtube.com/watch?v=ztspvPYybIY もちろん、答えは何もありませんでした。 データベースが応答するのを待っていました。
Django ORM •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM
Django ORM •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM •ORMasyncioରԠ͍ͯ͠ͳ͍
Django ORM •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM •ඇಉظIOͷརΛ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ •ORMasyncioରԠ͍ͯ͠ͳ͍
Django ORM •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM •ඇಉظIOͷརΛ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ •ͪΖΜσʔλϕʔεͷΞΫηε༗ޮ •ORMasyncioରԠ͍ͯ͠ͳ͍
Django ORM •DjangoΛར༻͢Δ্Ͱɺେ͖ͳັྗͷͻͱͭ ORM •ඇಉظIOͷརΛ֎෦ͷೖग़ྗͱઆ໌͖ͯ͠·ͨ͠ʢओʹωοτϫʔΫʣ •ͪΖΜσʔλϕʔεͷΞΫηε༗ޮ •ࠓ͞Θ͍ͬͯΔΞϓϦέʔγϣϯΛࢥ͍ग़͍ͯͩ͘͠͞ɻDB͕ඇಉظʹͳͬͨΒ… •ORMasyncioରԠ͍ͯ͠ͳ͍
Async ORM •Async ORM ͷಓ •PyConline AU 2020 "Taking Django's
ORM Async” •Django ίΞ developer Andrew Godwin ͞Μ
Async ORM •Async ORM ͷಓ •APIͷσβΠϯ͕ॏཁͩ •ͨͩɺasync DBAPI ·ͩͳ͍… •՝͋Δ
•Model API / ΫΤϦ / DBΞμϓλʔ ͱରԠ͍ͯ͘͠ܭը
Async ORM •Async ORM ͷಓ •ඇಉظΛՄೳͳݶΓ࠷ߴͷͷʹ͢Δ͜ͱΛ͓͑͠·͢ 🎉🎉🎉 •҆શͳඇಉظϓϩάϥϛϯά •͕ͯ͢ඇಉظͰɺඇಉظͰΤϥʔ͕ىͤ͜ͳ͍ੈքΛ࣮ݱ
Async ORM •۩ମతͳόʔδϣϯ…͏গ͔͔͠Γͦ͏Ͱ͢ •ָ͠ΈͰ͢Ͷ˒ IUUQTGPSVNEKBOHPQSPKFDUDPNUBTZODISPOPVTPSN
まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •Django async view - ಉظͱඇಉظ߹Θͤͯ IOόϯυͳॲཧΛத৺ʹ…
•Async ORM - ָ͠ΈͰ͢Ͷʂ ʢPyhtonͰ asyncio ରԠͷORMΞμϓλʔ͢Ͱʹ͍͔ͭ͋͘Γ·͢ɻʣ ·ͨɺDjangoOSSͰ͢ɻϦϙδτϦΛͷ͍ͧͯΈΔͷྑ͍͔͠Ε·ͤΜ 👀 IUUQTHJUIVCDPNEKBOHPEKBOHP
•ίϧʔνϯා͘ͳ͍ - 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
ご静聴ありがとうございました 👋