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
suspending functionの裏側
Search
Keita Kagurazaka
November 09, 2017
Programming
3
400
suspending functionの裏側
第07回Kotlin勉強会@Sansanでの発表資料です。
Keita Kagurazaka
November 09, 2017
Tweet
Share
More Decks by Keita Kagurazaka
See All by Keita Kagurazaka
SELECT FOR UPDATEの話
kkagurazaka
0
44
Mobileアプリのアーキテクチャ設計法
kkagurazaka
2
1.2k
原理から完全理解するDagger Hilt Migration
kkagurazaka
1
1.5k
今後のJetpackでAndroid開発はこう変わる!
kkagurazaka
16
5.7k
外部SDKのViewにマスク処理をする方法と罠
kkagurazaka
0
740
AWAのフルリニューアルを支えたアーキテクチャ
kkagurazaka
1
740
CQRS Architecture on Android
kkagurazaka
7
2.7k
coroutinesで非同期ページネーション
kkagurazaka
1
540
async/awaitで快適非同期ライフ
kkagurazaka
4
1.7k
Other Decks in Programming
See All in Programming
if constexpr文はテンプレート世界のラムダ式である
faithandbrave
3
670
Milestoner
bkuhlmann
1
410
PHPはいつから死んでいるかの調査
chiroruxx
2
420
Goのmultiple errorsについて (2024年4月版)
syumai
4
1.2k
『Railsオワコン』と言われる時代に、なぜブルーモ証券はRailsを選ぶのか
free_world21
1
360
try! Swift Tokyo 2024 参加報告 / try! Swift Tokyo 2024 Report
hironytic
0
220
DMMプラットフォームがTiDB Cloudを採用した背景
pospome
9
4.2k
GitHub Copilotのススメ
marcy731
1
220
Compose-View Interop in Practice (mDevCamp 2024)
stewemetal
0
170
Fast JSX: Don't clone props object #28768
yossydev
1
180
雑に思考を整理する技術と効能
konifar
63
30k
スキーマ駆動開発による品質とスピードの両立 - 私達は何故、スキーマを書くのか
kentaroutakeda
0
180
Featured
See All Featured
What the flash - Photography Introduction
edds
64
11k
How to train your dragon (web standard)
notwaldorf
75
5.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
188
16k
Debugging Ruby Performance
tmm1
70
11k
A designer walks into a library…
pauljervisheath
201
23k
The World Runs on Bad Software
bkeepers
PRO
61
6.7k
Rails Girls Zürich Keynote
gr2m
91
13k
Producing Creativity
orderedlist
PRO
338
39k
How STYLIGHT went responsive
nonsquared
92
4.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
32
46k
Music & Morning Musume
bryan
41
5.6k
Building Effective Engineering Teams - LeadDev
addyosmani
31
1.9k
Transcript
suspending functionの裏側 2017/11/9 第7回Kotlin勉強会@Sansan @kkagurazaka
皆さん、coroutines使ってますか?
KotlinConf Keynote Recap
KotlinConf Keynote Recap
None
coroutines じゃんじゃん使っていきましょう
そんなcoroutinesが どうやって実現されているか その裏側をお話します
自己紹介 • Keita Kagurazaka • Android App Developer • Sansan株式会社
2017/4〜 • Kotlin / CQRS / DDD / Splatoon / Github: @k-kagurazaka Twitter: @kkagurazaka
coroutinesとは • 中断・再開可能な計算のインスタンス ◦ Threadクラスのように、作成して実行する launch(UI) { val token =
fetchToken() // Tokenが取得できるまで実行を中断 val item = postItem(token, newItem) // 投稿が完了するまで実行を中断 updateUI(item) }
どのように中断・再開を 実現しているのか?
suspending function
suspending function • 呼び出されるとcoroutinesを中断する(こともできる) • suspending functionはcoroutinesかsuspending functionか らしか呼び出せない •
Java byte codeになる際にCPS transformされる
suspending function • 呼び出されるとcoroutinesを中断する(こともできる) • suspending functionはcoroutinesかsuspending functionか らしか呼び出せない •
Java byte codeになる際にCPS transformされる
Continuation Passing Style (CPS) 戻り値で値を返すのではなく、引数のContinuationインスタンスに 結果を渡すことで値を伝達するスタイル interface Continuation<in T> {
// 成功したことと、その結果を伝達 fun resume(value: T): Unit //失敗したことと、原因の例外を伝達 fun resumeWithException(exception: Throwable): Unit }
CPS transform // Kotlinでの宣言 suspend fun fetchToken(): Token // 変換後のJava
byte codeをKotlinっぽく書いたもの fun fetchToken(continuation: Continuation<Token>): Any? • 中断する場合は COROUTINE_SUSPENDED 定数を返し、 再開するときにContinuationをresumeする • 中断しない場合は結果の T を返す
CPS transform後のイメージ launch(UI) { fetchToken(object : Continuation<Token> { override fun
resume(value: Token) { postItem(value, newItem, object: Continuation<Item> { override fun resume(value: Item) { updateUI(value) } }) } }) } suspending functionの呼び出し以降がContinuationを介した コールバックに変換される
内部的な実装とはいえ コールバックのネストが 深すぎないか?
ステートマシンによる実装 class StateMachine implements Continuation<Object> { int label = 0;
// ステートマシンの状態 Token token; // suspending functionのローカル変数 Item item; // 同上 void resume(Object data) { … } }
void resume(Object data) { switch(label) { case 0: label =
1; data = fetchToken(this); // CPS変換後なのでContinuation=thisを渡す if (data == COROUTINE_SUSPENDED) break; // 中断が発生した場合は抜ける case 1: token = (Token)data; label = 2; data = postItem(token, newItem, this); if (data == COROUTINE_SUSPENDED) break; case 2: item = (Item)data; updateUI(item) label = -1; // ステートマシンの終了 break; } }
内部実装がコールバックヘル というわけではない!
まとめ • coroutineの中断はsuspending functionで発生する • suspending functionはCPS transformによってコールバック に変換される •
複数のsuspending functionの呼び出しはステートマシンにコ ンパイルされる
Thanks!