deep dive into coroutines on jvm @ kotlinconf 2017
TRANSCRIPT
![Page 1: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/1.jpg)
elizarov at JetBrainsRoman Elizarov
Deep dive into Coroutines on JVM
![Page 2: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/2.jpg)
There is no magic
![Page 3: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/3.jpg)
Continuation Passing Style (CPS)
![Page 4: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/4.jpg)
A toy problem
fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}Direct style
![Page 5: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/5.jpg)
Direct style
fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}
![Page 6: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/6.jpg)
Direct style
fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}Continuation
![Page 7: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/7.jpg)
Continuation-Passing Style
fun postItem(item: Item) {requestToken { token ->
val post = createPost(token, item)processPost(post)
}}
Continuation
CPS == Callbacks
![Page 8: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/8.jpg)
Continuation-Passing Style
fun postItem(item: Item) {requestToken { token ->
createPost(token, item) { post ->processPost(post)
}}
}
![Page 9: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/9.jpg)
Coroutines Direct Style
suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}
![Page 10: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/10.jpg)
How does it work?Behind the scenes
![Page 11: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/11.jpg)
Kotlin suspending functionsKotlin
suspend fun createPost(token: Token, item: Item): Post { … }
![Page 12: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/12.jpg)
CPS Transformation
Java/JVM
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
![Page 13: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/13.jpg)
CPS Transformation
callbackJava/JVM
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
![Page 14: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/14.jpg)
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {val context: CoroutineContextfun resume(value: T)fun resumeWithException(exception: Throwable)
}
![Page 15: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/15.jpg)
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {val context: CoroutineContextfun resume(value: T)fun resumeWithException(exception: Throwable)
}
![Page 16: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/16.jpg)
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {val context: CoroutineContextfun resume(value: T)fun resumeWithException(exception: Throwable)
}
![Page 17: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/17.jpg)
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {val context: CoroutineContextfun resume(value: T)fun resumeWithException(exception: Throwable)
}
![Page 18: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/18.jpg)
Continuation
Continuation is a generic callback interface
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {val context: CoroutineContextfun resume(value: T)fun resumeWithException(exception: Throwable)
}
![Page 19: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/19.jpg)
Direct to CPS
![Page 20: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/20.jpg)
Direct code
suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}
![Page 21: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/21.jpg)
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)}
Initial continuation
![Page 22: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/22.jpg)
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)}
Continuation
![Page 23: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/23.jpg)
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)} Continuation
Convert to CPS?
![Page 24: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/24.jpg)
Callbacks?
fun postItem(item: Item) {
requestToken { token ->
createPost(token, item) { post ->
processPost(post)
}}
}
![Page 25: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/25.jpg)
Labels
suspend fun postItem(item: Item) {// LABEL 0
val token = requestToken()// LABEL 1
val post = createPost(token, item)// LABEL 2
processPost(post)}
![Page 26: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/26.jpg)
Labels
suspend fun postItem(item: Item) {switch (label) {case 0:
val token = requestToken()case 1:
val post = createPost(token, item)case 2:
processPost(post)}
}
![Page 27: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/27.jpg)
suspend fun postItem(item: Item) {val sm = object : CoroutineImpl { … }switch (sm.label) {case 0:
val token = requestToken()case 1:
val post = createPost(token, item)case 2:
processPost(post)}
}
State
![Page 28: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/28.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = object : CoroutineImpl { … }switch (sm.label) {case 0:
requestToken(sm)case 1:
createPost(token, item, sm)case 2:
processPost(post)}
}
CPS Transform
![Page 29: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/29.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = …switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:createPost(token, item, sm)
case 2:processPost(post)
}}
Save state
![Page 30: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/30.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = object : CoroutineImpl { … }switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:createPost(token, item, sm)
case 2:processPost(post)
}}
Callback
State Machine as Continuation
![Page 31: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/31.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = object : CoroutineImpl {
fun resume(…) {postItem(null, this)
}}switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:createPost(token, item, sm)
…}
Callback
![Page 32: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/32.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = cont as? ThisSM ?: object : ThisSM {
fun resume(…) {postItem(null, this)
}}switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:createPost(token, item, sm)
…}
Callback
![Page 33: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/33.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = …switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:val item = sm.itemval token = sm.result as Tokensm.label = 2createPost(token, item, sm)
…}
Restore state
![Page 34: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/34.jpg)
fun postItem(item: Item, cont: Continuation) {val sm = …switch (sm.label) {case 0:
sm.item = itemsm.label = 1requestToken(sm)
case 1:val item = sm.itemval token = sm.result as Tokensm.label = 2createPost(token, item, sm)
…}
Continue
![Page 35: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/35.jpg)
State Machine vs Callbacks
fun postItem(item: Item) {requestToken { token ->
createPost(token, item) { post ->processPost(post)
}}
}
suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}
![Page 36: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/36.jpg)
State Machine vs Callbacks
fun postItem(item: Item) {requestToken { token ->
createPost(token, item) { post ->processPost(post)
}}
}
suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)
}
Reuse closure / state object
Create new closure
![Page 37: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/37.jpg)
State Machine vs Callbackssuspend fun postItems(items: List<Item>) {
for (item in items) {val token = requestToken()val post = createPost(token, item)processPost(post)
}}
Easy loops and higher-order functions
![Page 38: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/38.jpg)
State Machine vs Callbacks
fun postItems(items: List<Item>) {…
}
suspend fun postItems(items: List<Item>) {for (item in items) {
val token = requestToken()val post = createPost(token, item)processPost(post)
}}
A horrid callback mess
Easy loops and higher-order functions
![Page 39: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/39.jpg)
Integration
![Page 40: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/40.jpg)
Zoo of futures on JVM
![Page 41: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/41.jpg)
interface Service {fun createPost(token: Token, item: Item): Call<Post>
}
![Page 42: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/42.jpg)
interface Service {fun createPost(token: Token, item: Item): Call<Post>
}
suspend fun createPost(token: Token, item: Item): Post =serviceInstance.createPost(token, item).await()
![Page 43: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/43.jpg)
suspend fun <T> Call<T>.await(): T {…
}
![Page 44: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/44.jpg)
Callbacks everywheresuspend fun <T> Call<T>.await(): T {
enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {
// todo}
override fun onFailure(call: Call<T>, t: Throwable) {// todo
}})
}
![Page 45: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/45.jpg)
suspend fun <T> Call<T>.await(): T = suspendCoroutine { cont ->enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {if (response.isSuccessful)
cont.resume(response.body()!!)else
cont.resumeWithException(ErrorResponse(response))}
override fun onFailure(call: Call<T>, t: Throwable) {cont.resumeWithException(t)
}})
}
![Page 46: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/46.jpg)
suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T
![Page 47: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/47.jpg)
suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T
Regular function
Inspired by call/cc from Scheme
![Page 48: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/48.jpg)
Install callbacksuspend fun <T> Call<T>.await(): T = suspendCoroutine { cont ->
enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful)cont.resume(response.body()!!)
elsecont.resumeWithException(ErrorResponse(response))
}
override fun onFailure(call: Call<T>, t: Throwable) {cont.resumeWithException(t)
}})
}
![Page 49: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/49.jpg)
Install callbacksuspend fun <T> Call<T>.await(): T = suspendCoroutine { cont ->
enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful)cont.resume(response.body()!!)
elsecont.resumeWithException(ErrorResponse(response))
}
override fun onFailure(call: Call<T>, t: Throwable) {cont.resumeWithException(t)
}})
}
![Page 50: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/50.jpg)
Analyze responsesuspend fun <T> Call<T>.await(): T = suspendCoroutine { cont ->
enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful)cont.resume(response.body()!!)
elsecont.resumeWithException(ErrorResponse(response))
}
override fun onFailure(call: Call<T>, t: Throwable) {cont.resumeWithException(t)
}})
}
![Page 51: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/51.jpg)
Analyze responsesuspend fun <T> Call<T>.await(): T = suspendCoroutine { cont ->
enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful)cont.resume(response.body()!!)
elsecont.resumeWithException(ErrorResponse(response))
}
override fun onFailure(call: Call<T>, t: Throwable) {cont.resumeWithException(t)
}})
}That’s all
![Page 52: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/52.jpg)
Out-of-the box integrations
kotlinx-coroutines-core
jdk8
guava
nio
reactor
rx1
rx2
Contributions are welcome
![Page 53: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/53.jpg)
Coroutine context
![Page 54: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/54.jpg)
What thread it resumes on?
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)}
Continuation
It depends!
![Page 55: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/55.jpg)
What thread it resumes on?
fun postItem(item: Item) {launch(UI) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)}
}
Continuation
![Page 56: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/56.jpg)
Continuation Interceptorinterface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):Continuation<T>
}
![Page 57: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/57.jpg)
Continuation Interceptorinterface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):Continuation<T>
}
![Page 58: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/58.jpg)
Continuation Interceptorinterface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):Continuation<T>
}
![Page 59: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/59.jpg)
Dispatched continuation
class DispatchedContinuation<in T>(val dispatcher: CoroutineDispatcher,val continuation: Continuation<T>
): Continuation<T> by continuation {
override fun resume(value: T) {dispatcher.dispatch(context, DispatchTask(…))
}
…} Dispatches execution to another thread
![Page 60: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/60.jpg)
Starting coroutines
![Page 61: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/61.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T>
Coroutine builder
![Page 62: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/62.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T>
A regular function
![Page 63: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/63.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T>
![Page 64: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/64.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T> suspending lambda
![Page 65: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/65.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T> {val future = CompletableFuture<T>()block.startCoroutine(…)return future
}
![Page 66: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/66.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T> {val future = CompletableFuture<T>()block.startCoroutine(…)return future
}
![Page 67: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/67.jpg)
fun <T> future(context: CoroutineContext = DefaultDispatcher,block: suspend () -> T
): CompletableFuture<T> {val future = CompletableFuture<T>()block.startCoroutine(completion = object : Continuation<T> {
…})return future
}
![Page 68: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/68.jpg)
fun <T> future(…): CompletableFuture<T> {val future = CompletableFuture<T>()block.startCoroutine(completion = object : Continuation<T> {
override val context: CoroutineContext get() = context
override fun resume(value: T) {future.complete(value)
}
override fun resumeWithException(exception: Throwable) {future.completeExceptionally(exception)
}})return future
}
![Page 69: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/69.jpg)
fun <T> future(…): CompletableFuture<T> {val future = CompletableFuture<T>()block.startCoroutine(completion = object : Continuation<T> {
override val context: CoroutineContext get() = context
override fun resume(value: T) {future.complete(value)
}
override fun resumeWithException(exception: Throwable) {future.completeExceptionally(exception)
}})return future
}That’s all, folks!
![Page 70: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/70.jpg)
Job cancellation
![Page 71: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/71.jpg)
Launch coroutine builderfun launch(
context: CoroutineContext = DefaultDispatcher,block: suspend () -> Unit
): Job { … }
![Page 72: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/72.jpg)
Launching coroutineval job = launch {
…}
![Page 73: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/73.jpg)
val job = launch { …
}
job.join()
![Page 74: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/74.jpg)
val job = launch { …
}
job.join()job.cancel()
![Page 75: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/75.jpg)
Jobinterface Job : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<Job>
…}
![Page 76: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/76.jpg)
Using coroutine contextlaunch {
val job = coroutineContext[Job]!!…
}
![Page 77: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/77.jpg)
Using coroutine contextlaunch {
val job = coroutineContext[Job]!!val interceptor = coroutineContext[CoroutineInterceptor]!!…
}
![Page 78: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/78.jpg)
Timeoutslaunch {
withTimeout(10, TimeUnit.SECONDS) {…
}}
![Page 79: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/79.jpg)
Cooperative cancellation
![Page 80: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/80.jpg)
Cooperative cancellationlaunch {
while (true) {…
}}
![Page 81: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/81.jpg)
Cooperative cancellationlaunch {
while (isActive) {…
}}
![Page 82: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/82.jpg)
Cooperative cancellationlaunch {
while (true) {delay(…)…
}}
![Page 83: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/83.jpg)
Cancellable suspensionsuspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont ->enqueue(…)
}
![Page 84: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/84.jpg)
Cancellable continuationsuspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->enqueue(…)
}
![Page 85: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/85.jpg)
Completion handlersuspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->enqueue(…)cont.invokeOnCompletion {
}
![Page 86: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/86.jpg)
Completion handlersuspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->enqueue(…)cont.invokeOnCompletion {
}
![Page 87: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/87.jpg)
Communicating Sequential Processes (CSP)
![Page 88: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/88.jpg)
Shared Mutable State
@stefanobaghino
![Page 89: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/89.jpg)
The choice
SharedMutable State
Share by Communicating
![Page 90: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/90.jpg)
Examplefun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 91: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/91.jpg)
Main coroutinefun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 92: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/92.jpg)
Channelfun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 93: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/93.jpg)
Launchfun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
Child coroutine
![Page 94: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/94.jpg)
Coroutine bodyfun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
Sequential code!
![Page 95: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/95.jpg)
Sendfun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 96: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/96.jpg)
Closefun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 97: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/97.jpg)
Receive for loopfun main(args: Array<String>) = runBlocking<Unit> {
val chan = Channel<Int>()launch(coroutineContext) {
repeat(10) { i ->delay(100)chan.send(i)
}chan.close()
}launch(coroutineContext) {
for (i in chan) {println(i)
}}
}
![Page 98: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/98.jpg)
Demo
![Page 99: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/99.jpg)
ActorsThe other way to look at CSP
![Page 100: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/100.jpg)
The choice
Named channels
Namedcoroutines
Actor == named coroutine & inbox channel
![Page 101: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/101.jpg)
Examplefun main(args: Array<String>) = runBlocking<Unit> {
val printer = actor<Int>(coroutineContext) {for (i in channel) {
println(i)}
}launch(coroutineContext) {
repeat(10) { i ->delay(100)printer.send(i)
}printer.close()
}}
![Page 102: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/102.jpg)
Actor coroutine builderfun main(args: Array<String>) = runBlocking<Unit> {
val printer = actor<Int>(coroutineContext) {for (i in channel) {
println(i)}
}launch(coroutineContext) {
repeat(10) { i ->delay(100)printer.send(i)
}printer.close()
}}
![Page 103: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/103.jpg)
Actor bodyfun main(args: Array<String>) = runBlocking<Unit> {
val printer = actor<Int>(coroutineContext) {for (i in channel) {
println(i)}
}launch(coroutineContext) {
repeat(10) { i ->delay(100)printer.send(i)
}printer.close()
}}
Sequential!
![Page 104: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/104.jpg)
Interacting with an actorfun main(args: Array<String>) = runBlocking<Unit> {
val printer = actor<Int>(coroutineContext) {for (i in channel) {
println(i)}
}launch(coroutineContext) {
repeat(10) { i ->delay(100)printer.send(i)
}printer.close()
}}
![Page 105: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/105.jpg)
References
![Page 106: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/106.jpg)
Guide to kotlinx.coroutinesby example
https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
• Basics• Cancellation and Timeouts• Composition• Coroutine contexts• Channels• Shared Mutable State and Concurrency• Select expressions
![Page 107: Deep dive into Coroutines on JVM @ KotlinConf 2017](https://reader034.vdocuments.net/reader034/viewer/2022042600/5a6487337f8b9a27568b5afd/html5/thumbnails/107.jpg)
#kotlinconf17
relizarovelizarov at JetBrains
Roman Elizarov
Thank you
Any questions?