SlideShare a Scribd company logo
elizarov at JetBrains
Roman Elizarov
Deep dive into Coroutines
on JVM
There is no magic
Continuation Passing
Style (CPS)
A toy problem
fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Direct style
Direct style
fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Direct style
fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Continuation
Continuation-Passing Style
fun postItem(item: Item) {
requestToken { token ->
val post = createPost(token, item)
processPost(post)
}
}
Continuation
CPS == Callbacks
Continuation-Passing Style
fun postItem(item: Item) {
requestToken { token ->
createPost(token, item) { post ->
processPost(post)
}
}
}
Coroutines Direct Style
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
How does it work?
Behind the scenes
Kotlin suspending functions
Kotlin
suspend fun createPost(token: Token, item: Item): Post { … }
CPS Transformation
Java/JVM
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
CPS Transformation
callback
Java/JVM
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Continuation
suspend fun createPost(token: Token, item: Item): Post { … }
Object createPost(Token token, Item item, Continuation<Post> cont) { … }
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
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: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Direct to CPS
Direct code
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Initial continuation
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Continuation
Continuations
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Continuation
Convert to CPS?
Callbacks?
fun postItem(item: Item) {
requestToken { token ->
createPost(token, item) { post ->
processPost(post)
}
}
}
Labels
suspend fun postItem(item: Item) {
// LABEL 0
val token = requestToken()
// LABEL 1
val post = createPost(token, item)
// LABEL 2
processPost(post)
}
Labels
suspend fun postItem(item: Item) {
switch (label) {
case 0:
val token = requestToken()
case 1:
val post = createPost(token, item)
case 2:
processPost(post)
}
}
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
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
fun postItem(item: Item, cont: Continuation) {
val sm = …
switch (sm.label) {
case 0:
sm.item = item
sm.label = 1
requestToken(sm)
case 1:
createPost(token, item, sm)
case 2:
processPost(post)
}
}
Save state
fun postItem(item: Item, cont: Continuation) {
val sm = object : CoroutineImpl { … }
switch (sm.label) {
case 0:
sm.item = item
sm.label = 1
requestToken(sm)
case 1:
createPost(token, item, sm)
case 2:
processPost(post)
}
}
Callback
State Machine as Continuation
fun postItem(item: Item, cont: Continuation) {
val sm = object : CoroutineImpl {
fun resume(…) {
postItem(null, this)
}
}
switch (sm.label) {
case 0:
sm.item = item
sm.label = 1
requestToken(sm)
case 1:
createPost(token, item, sm)
…
}
Callback
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 = item
sm.label = 1
requestToken(sm)
case 1:
createPost(token, item, sm)
…
}
Callback
fun postItem(item: Item, cont: Continuation) {
val sm = …
switch (sm.label) {
case 0:
sm.item = item
sm.label = 1
requestToken(sm)
case 1:
val item = sm.item
val token = sm.result as Token
sm.label = 2
createPost(token, item, sm)
…
}
Restore state
fun postItem(item: Item, cont: Continuation) {
val sm = …
switch (sm.label) {
case 0:
sm.item = item
sm.label = 1
requestToken(sm)
case 1:
val item = sm.item
val token = sm.result as Token
sm.label = 2
createPost(token, item, sm)
…
}
Continue
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)
}
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
State Machine vs Callbacks
suspend 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
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
Integration
Zoo of futures on JVM
interface Service {
fun createPost(token: Token, item: Item): Call<Post>
}
interface Service {
fun createPost(token: Token, item: Item): Call<Post>
}
suspend fun createPost(token: Token, item: Item): Post =
serviceInstance.createPost(token, item).await()
suspend fun <T> Call<T>.await(): T {
…
}
Callbacks everywhere
suspend 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
}
})
}
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)
}
})
}
suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T
suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T
Regular function
Inspired by call/cc from Scheme
Install callback
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)
}
})
}
Install callback
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)
}
})
}
Analyze response
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)
}
})
}
Analyze response
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)
}
})
}
That’s all
Out-of-the box integrations
kotlinx-coroutines-core
jdk8
guava
nio
reactor
rx1
rx2
Contributions are welcome
Coroutine context
What thread it resumes on?
suspend fun postItem(item: Item) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
Continuation
It depends!
What thread it resumes on?
fun postItem(item: Item) {
launch(UI) {
val token = requestToken()
val post = createPost(token, item)
processPost(post)
}
}
Continuation
Continuation Interceptor
interface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):
Continuation<T>
}
Continuation Interceptor
interface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):
Continuation<T>
}
Continuation Interceptor
interface ContinuationInterceptor : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<ContinuationInterceptor>
fun <T> interceptContinuation(continuation: Continuation<T>):
Continuation<T>
}
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
Starting coroutines
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T>
Coroutine builder
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T>
A regular function
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T>
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T> suspending lambda
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T> {
val future = CompletableFuture<T>()
block.startCoroutine(…)
return future
}
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T> {
val future = CompletableFuture<T>()
block.startCoroutine(…)
return future
}
fun <T> future(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> T
): CompletableFuture<T> {
val future = CompletableFuture<T>()
block.startCoroutine(completion = object : Continuation<T> {
…
})
return future
}
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
}
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!
Job cancellation
Launch coroutine builder
fun launch(
context: CoroutineContext = DefaultDispatcher,
block: suspend () -> Unit
): Job { … }
Launching coroutine
val job = launch {
…
}
val job = launch {
…
}
job.join()
val job = launch {
…
}
job.join()
job.cancel()
Job
interface Job : CoroutineContext.Element {
companion object Key : CoroutineContext.Key<Job>
…
}
Using coroutine context
launch {
val job = coroutineContext[Job]!!
…
}
Using coroutine context
launch {
val job = coroutineContext[Job]!!
val interceptor = coroutineContext[CoroutineInterceptor]!!
…
}
Timeouts
launch {
withTimeout(10, TimeUnit.SECONDS) {
…
}
}
Cooperative cancellation
Cooperative cancellation
launch {
while (true) {
…
}
}
Cooperative cancellation
launch {
while (isActive) {
…
}
}
Cooperative cancellation
launch {
while (true) {
delay(…)
…
}
}
Cancellable suspension
suspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont ->
enqueue(…)
}
Cancellable continuation
suspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
enqueue(…)
}
Completion handler
suspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
enqueue(…)
cont.invokeOnCompletion {
this@await.cancel()
}
}
Completion handler
suspend fun <T> Call<T>.await(): T =
suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
enqueue(…)
cont.invokeOnCompletion {
this@await.cancel()
}
}
Communicating Sequential
Processes (CSP)
Shared Mutable State
@stefanobaghino
The choice
Shared
Mutable State
Share by
Communicating
Example
fun 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)
}
}
}
Main coroutine
fun 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)
}
}
}
Channel
fun 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)
}
}
}
Launch
fun 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
Coroutine body
fun 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!
Send
fun 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)
}
}
}
Close
fun 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)
}
}
}
Receive for loop
fun 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)
}
}
}
Demo
Actors
The other way to look at CSP
The choice
Named
channels
Named
coroutines
Actor == named coroutine & inbox channel
Example
fun 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()
}
}
Actor coroutine builder
fun 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()
}
}
Actor body
fun 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!
Interacting with an actor
fun 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()
}
}
References
Guide to kotlinx.coroutines
by 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
#kotlinconf17
relizarov
elizarov at JetBrains
Roman Elizarov
Thank you
Any questions?

More Related Content

What's hot

Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android application
Seven Peaks Speaks
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenes
Anh Vu
 
Kotlin coroutines
Kotlin coroutinesKotlin coroutines
Kotlin coroutines
Robert Levonyan
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
Scott Wlaschin
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Mario Fusco
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
Dmytro Zaitsev
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Lauren Yew
 
History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)
Yoshifumi Kawai
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin Flows
GlobalLogic Ukraine
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett Welson
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
NAVER / MusicPlatform
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
Arawn Park
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
RichardWarburton
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
Christian Melchior
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)
Scott Wlaschin
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
José Paumard
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Designveloper
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)
Scott Wlaschin
 
Android kotlin coroutines
Android kotlin coroutinesAndroid kotlin coroutines
Android kotlin coroutines
Bipin Vayalu
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 

What's hot (20)

Utilizing kotlin flows in an android application
Utilizing kotlin flows in an android applicationUtilizing kotlin flows in an android application
Utilizing kotlin flows in an android application
 
Kotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenesKotlin coroutine - behind the scenes
Kotlin coroutine - behind the scenes
 
Kotlin coroutines
Kotlin coroutinesKotlin coroutines
Kotlin coroutines
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin CoroutinesThreading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
 
History & Practices for UniRx(EN)
History & Practices for UniRx(EN)History & Practices for UniRx(EN)
History & Practices for UniRx(EN)
 
In-depth analysis of Kotlin Flows
In-depth analysis of Kotlin FlowsIn-depth analysis of Kotlin Flows
In-depth analysis of Kotlin Flows
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)
 
Android kotlin coroutines
Android kotlin coroutinesAndroid kotlin coroutines
Android kotlin coroutines
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 

Viewers also liked

Using Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems EasyUsing Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems Easy
nathanmarz
 
Анализ количества посетителей на сайте [Считаем уникальные элементы]
Анализ количества посетителей на сайте [Считаем уникальные элементы]Анализ количества посетителей на сайте [Считаем уникальные элементы]
Анализ количества посетителей на сайте [Считаем уникальные элементы]
Qrator Labs
 
ReqLabs PechaKucha Евгений Сафроненко
ReqLabs PechaKucha Евгений СафроненкоReqLabs PechaKucha Евгений Сафроненко
ReqLabs PechaKucha Евгений Сафроненко
PechaKucha Ukraine
 
HyperLogLog in Hive - How to count sheep efficiently?
HyperLogLog in Hive - How to count sheep efficiently?HyperLogLog in Hive - How to count sheep efficiently?
HyperLogLog in Hive - How to count sheep efficiently?
bzamecnik
 
Probabilistic data structures. Part 2. Cardinality
Probabilistic data structures. Part 2. CardinalityProbabilistic data structures. Part 2. Cardinality
Probabilistic data structures. Part 2. Cardinality
Andrii Gakhov
 
Big Data aggregation techniques
Big Data aggregation techniquesBig Data aggregation techniques
Big Data aggregation techniques
Valentin Logvinskiy
 
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
Data Con LA
 
Probabilistic data structures
Probabilistic data structuresProbabilistic data structures
Probabilistic data structures
shrinivasvasala
 
Hyper loglog
Hyper loglogHyper loglog
Hyper loglog
nybon
 
Walk through an enterprise Linux migration
Walk through an enterprise Linux migrationWalk through an enterprise Linux migration
Walk through an enterprise Linux migration
Rogue Wave Software
 
Graduating To Go - A Jumpstart into the Go Programming Language
Graduating To Go - A Jumpstart into the Go Programming LanguageGraduating To Go - A Jumpstart into the Go Programming Language
Graduating To Go - A Jumpstart into the Go Programming Language
Kaylyn Gibilterra
 
Scale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneScale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOne
Roman Elizarov
 
numPYNQ @ NGCLE@e-Novia 15.11.2017
numPYNQ @ NGCLE@e-Novia 15.11.2017numPYNQ @ NGCLE@e-Novia 15.11.2017
numPYNQ @ NGCLE@e-Novia 15.11.2017
NECST Lab @ Politecnico di Milano
 
What in the World is Going on at The Linux Foundation?
What in the World is Going on at The Linux Foundation?What in the World is Going on at The Linux Foundation?
What in the World is Going on at The Linux Foundation?
Black Duck by Synopsys
 
Docker Networking
Docker NetworkingDocker Networking
Docker Networking
Kingston Smiler
 
Communication hardware
Communication hardwareCommunication hardware
Communication hardware
Hans Mallen
 
In-Memory Computing Essentials for Architects and Engineers
In-Memory Computing Essentials for Architects and EngineersIn-Memory Computing Essentials for Architects and Engineers
In-Memory Computing Essentials for Architects and Engineers
Denis Magda
 
DevRomagna / Golang Intro
DevRomagna / Golang IntroDevRomagna / Golang Intro
DevRomagna / Golang Intro
Simone Gentili
 
Advanced memory allocation
Advanced memory allocationAdvanced memory allocation
Advanced memory allocation
Joris Bonnefoy
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
Aj MaChInE
 

Viewers also liked (20)

Using Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems EasyUsing Simplicity to Make Hard Big Data Problems Easy
Using Simplicity to Make Hard Big Data Problems Easy
 
Анализ количества посетителей на сайте [Считаем уникальные элементы]
Анализ количества посетителей на сайте [Считаем уникальные элементы]Анализ количества посетителей на сайте [Считаем уникальные элементы]
Анализ количества посетителей на сайте [Считаем уникальные элементы]
 
ReqLabs PechaKucha Евгений Сафроненко
ReqLabs PechaKucha Евгений СафроненкоReqLabs PechaKucha Евгений Сафроненко
ReqLabs PechaKucha Евгений Сафроненко
 
HyperLogLog in Hive - How to count sheep efficiently?
HyperLogLog in Hive - How to count sheep efficiently?HyperLogLog in Hive - How to count sheep efficiently?
HyperLogLog in Hive - How to count sheep efficiently?
 
Probabilistic data structures. Part 2. Cardinality
Probabilistic data structures. Part 2. CardinalityProbabilistic data structures. Part 2. Cardinality
Probabilistic data structures. Part 2. Cardinality
 
Big Data aggregation techniques
Big Data aggregation techniquesBig Data aggregation techniques
Big Data aggregation techniques
 
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
Big Data Day LA 2015 - Large Scale Distinct Count -- The HyperLogLog algorith...
 
Probabilistic data structures
Probabilistic data structuresProbabilistic data structures
Probabilistic data structures
 
Hyper loglog
Hyper loglogHyper loglog
Hyper loglog
 
Walk through an enterprise Linux migration
Walk through an enterprise Linux migrationWalk through an enterprise Linux migration
Walk through an enterprise Linux migration
 
Graduating To Go - A Jumpstart into the Go Programming Language
Graduating To Go - A Jumpstart into the Go Programming LanguageGraduating To Go - A Jumpstart into the Go Programming Language
Graduating To Go - A Jumpstart into the Go Programming Language
 
Scale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneScale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOne
 
numPYNQ @ NGCLE@e-Novia 15.11.2017
numPYNQ @ NGCLE@e-Novia 15.11.2017numPYNQ @ NGCLE@e-Novia 15.11.2017
numPYNQ @ NGCLE@e-Novia 15.11.2017
 
What in the World is Going on at The Linux Foundation?
What in the World is Going on at The Linux Foundation?What in the World is Going on at The Linux Foundation?
What in the World is Going on at The Linux Foundation?
 
Docker Networking
Docker NetworkingDocker Networking
Docker Networking
 
Communication hardware
Communication hardwareCommunication hardware
Communication hardware
 
In-Memory Computing Essentials for Architects and Engineers
In-Memory Computing Essentials for Architects and EngineersIn-Memory Computing Essentials for Architects and Engineers
In-Memory Computing Essentials for Architects and Engineers
 
DevRomagna / Golang Intro
DevRomagna / Golang IntroDevRomagna / Golang Intro
DevRomagna / Golang Intro
 
Advanced memory allocation
Advanced memory allocationAdvanced memory allocation
Advanced memory allocation
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
 

Similar to Deep dive into Coroutines on JVM @ KotlinConf 2017

200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
NAVER Engineering
 
Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
Roman Elizarov
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
UA Mobile
 
Kotlin의 코루틴은 어떻게 동작하는가
Kotlin의 코루틴은 어떻게 동작하는가Kotlin의 코루틴은 어떻게 동작하는가
Kotlin의 코루틴은 어떻게 동작하는가
Chang W. Doh
 
Dive into kotlins coroutines
Dive into kotlins coroutinesDive into kotlins coroutines
Dive into kotlins coroutines
Freddie Wang
 
Fresh Async with Kotlin
Fresh Async with KotlinFresh Async with Kotlin
Fresh Async with Kotlin
C4Media
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303
Alex Semin
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
iMasters
 
Programação assíncrona utilizando Coroutines
Programação assíncrona utilizando CoroutinesProgramação assíncrona utilizando Coroutines
Programação assíncrona utilizando Coroutines
Diego Gonçalves Santos
 
Kotlin coroutines
Kotlin coroutines Kotlin coroutines
Kotlin coroutines
TSE-JU LIN(Louis)
 
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando CoroutinesTDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
tdc-globalcode
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
John De Goes
 
Programação Assíncrona com Kotlin Coroutines
Programação Assíncrona com Kotlin CoroutinesProgramação Assíncrona com Kotlin Coroutines
Programação Assíncrona com Kotlin Coroutines
Lucas Borsatto
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
Adam Dudczak
 
week-18x
week-18xweek-18x
week-17x
week-17xweek-17x
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
tdc-globalcode
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
Richard Fox
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
Siarhiej Siemianchuk
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
Tor Ivry
 

Similar to Deep dive into Coroutines on JVM @ KotlinConf 2017 (20)

200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
 
Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
Kotlin의 코루틴은 어떻게 동작하는가
Kotlin의 코루틴은 어떻게 동작하는가Kotlin의 코루틴은 어떻게 동작하는가
Kotlin의 코루틴은 어떻게 동작하는가
 
Dive into kotlins coroutines
Dive into kotlins coroutinesDive into kotlins coroutines
Dive into kotlins coroutines
 
Fresh Async with Kotlin
Fresh Async with KotlinFresh Async with Kotlin
Fresh Async with Kotlin
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Programação assíncrona utilizando Coroutines
Programação assíncrona utilizando CoroutinesProgramação assíncrona utilizando Coroutines
Programação assíncrona utilizando Coroutines
 
Kotlin coroutines
Kotlin coroutines Kotlin coroutines
Kotlin coroutines
 
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando CoroutinesTDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
TDC2018SP | Trilha Kotlin - Programacao assincrona utilizando Coroutines
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
Programação Assíncrona com Kotlin Coroutines
Programação Assíncrona com Kotlin CoroutinesProgramação Assíncrona com Kotlin Coroutines
Programação Assíncrona com Kotlin Coroutines
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
week-18x
week-18xweek-18x
week-18x
 
week-17x
week-17xweek-17x
week-17x
 
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin WayTDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
TDC218SP | Trilha Kotlin - DSLs in a Kotlin Way
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
Concurrent Application Development using Scala
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
 
Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 

More from Roman Elizarov

Lock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin CoroutinesLock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin Coroutines
Roman Elizarov
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waiting
Roman Elizarov
 
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и Практика
Roman Elizarov
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!
Roman Elizarov
 
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
Why GC is eating all my CPU?
Why GC is eating all my CPU?Why GC is eating all my CPU?
Why GC is eating all my CPU?
Roman Elizarov
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)
Roman Elizarov
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Roman Elizarov
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
Roman Elizarov
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
Java Serialization Facts and Fallacies
Java Serialization Facts and FallaciesJava Serialization Facts and Fallacies
Java Serialization Facts and Fallacies
Roman Elizarov
 
Millions quotes per second in pure java
Millions quotes per second in pure javaMillions quotes per second in pure java
Millions quotes per second in pure java
Roman Elizarov
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmer
Roman Elizarov
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
Roman Elizarov
 

More from Roman Elizarov (17)

Lock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin CoroutinesLock-free algorithms for Kotlin Coroutines
Lock-free algorithms for Kotlin Coroutines
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waiting
 
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
 
Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и Практика
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!
 
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
 
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
 
Why GC is eating all my CPU?
Why GC is eating all my CPU?Why GC is eating all my CPU?
Why GC is eating all my CPU?
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
 
Java Serialization Facts and Fallacies
Java Serialization Facts and FallaciesJava Serialization Facts and Fallacies
Java Serialization Facts and Fallacies
 
Millions quotes per second in pure java
Millions quotes per second in pure javaMillions quotes per second in pure java
Millions quotes per second in pure java
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmer
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
 

Recently uploaded

Performance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy EvertsPerformance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy Everts
ScyllaDB
 
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum ThreatsNavigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
anupriti
 
Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
Safe Software
 
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Chris Swan
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
Emerging Tech
 
Blockchain and Cyber Defense Strategies in new genre times
Blockchain and Cyber Defense Strategies in new genre timesBlockchain and Cyber Defense Strategies in new genre times
Blockchain and Cyber Defense Strategies in new genre times
anupriti
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
Yevgen Sysoyev
 
What’s New in Teams Calling, Meetings and Devices May 2024
What’s New in Teams Calling, Meetings and Devices May 2024What’s New in Teams Calling, Meetings and Devices May 2024
What’s New in Teams Calling, Meetings and Devices May 2024
Stephanie Beckett
 
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
amitchopra0215
 
The Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU CampusesThe Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU Campuses
Larry Smarr
 
Data Protection in a Connected World: Sovereignty and Cyber Security
Data Protection in a Connected World: Sovereignty and Cyber SecurityData Protection in a Connected World: Sovereignty and Cyber Security
Data Protection in a Connected World: Sovereignty and Cyber Security
anupriti
 
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
Edge AI and Vision Alliance
 
What's Next Web Development Trends to Watch.pdf
What's Next Web Development Trends to Watch.pdfWhat's Next Web Development Trends to Watch.pdf
What's Next Web Development Trends to Watch.pdf
SeasiaInfotech2
 
K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024
The Digital Insurer
 
20240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 202420240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 2024
Matthew Sinclair
 
The Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive ComputingThe Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive Computing
Larry Smarr
 
Verti - EMEA Insurer Innovation Award 2024
Verti - EMEA Insurer Innovation Award 2024Verti - EMEA Insurer Innovation Award 2024
Verti - EMEA Insurer Innovation Award 2024
The Digital Insurer
 
Running a Go App in Kubernetes: CPU Impacts
Running a Go App in Kubernetes: CPU ImpactsRunning a Go App in Kubernetes: CPU Impacts
Running a Go App in Kubernetes: CPU Impacts
ScyllaDB
 
How RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptxHow RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptx
SynapseIndia
 
What Not to Document and Why_ (North Bay Python 2024)
What Not to Document and Why_ (North Bay Python 2024)What Not to Document and Why_ (North Bay Python 2024)
What Not to Document and Why_ (North Bay Python 2024)
Margaret Fero
 

Recently uploaded (20)

Performance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy EvertsPerformance Budgets for the Real World by Tammy Everts
Performance Budgets for the Real World by Tammy Everts
 
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum ThreatsNavigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
Navigating Post-Quantum Blockchain: Resilient Cryptography in Quantum Threats
 
Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
 
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
Fluttercon 2024: Showing that you care about security - OpenSSF Scorecards fo...
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
 
Blockchain and Cyber Defense Strategies in new genre times
Blockchain and Cyber Defense Strategies in new genre timesBlockchain and Cyber Defense Strategies in new genre times
Blockchain and Cyber Defense Strategies in new genre times
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
 
What’s New in Teams Calling, Meetings and Devices May 2024
What’s New in Teams Calling, Meetings and Devices May 2024What’s New in Teams Calling, Meetings and Devices May 2024
What’s New in Teams Calling, Meetings and Devices May 2024
 
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
@Call @Girls Pune 0000000000 Riya Khan Beautiful Girl any Time
 
The Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU CampusesThe Increasing Use of the National Research Platform by the CSU Campuses
The Increasing Use of the National Research Platform by the CSU Campuses
 
Data Protection in a Connected World: Sovereignty and Cyber Security
Data Protection in a Connected World: Sovereignty and Cyber SecurityData Protection in a Connected World: Sovereignty and Cyber Security
Data Protection in a Connected World: Sovereignty and Cyber Security
 
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
“Intel’s Approach to Operationalizing AI in the Manufacturing Sector,” a Pres...
 
What's Next Web Development Trends to Watch.pdf
What's Next Web Development Trends to Watch.pdfWhat's Next Web Development Trends to Watch.pdf
What's Next Web Development Trends to Watch.pdf
 
K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024K2G - Insurtech Innovation EMEA Award 2024
K2G - Insurtech Innovation EMEA Award 2024
 
20240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 202420240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 2024
 
The Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive ComputingThe Rise of Supernetwork Data Intensive Computing
The Rise of Supernetwork Data Intensive Computing
 
Verti - EMEA Insurer Innovation Award 2024
Verti - EMEA Insurer Innovation Award 2024Verti - EMEA Insurer Innovation Award 2024
Verti - EMEA Insurer Innovation Award 2024
 
Running a Go App in Kubernetes: CPU Impacts
Running a Go App in Kubernetes: CPU ImpactsRunning a Go App in Kubernetes: CPU Impacts
Running a Go App in Kubernetes: CPU Impacts
 
How RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptxHow RPA Help in the Transportation and Logistics Industry.pptx
How RPA Help in the Transportation and Logistics Industry.pptx
 
What Not to Document and Why_ (North Bay Python 2024)
What Not to Document and Why_ (North Bay Python 2024)What Not to Document and Why_ (North Bay Python 2024)
What Not to Document and Why_ (North Bay Python 2024)
 

Deep dive into Coroutines on JVM @ KotlinConf 2017

  • 1. elizarov at JetBrains Roman Elizarov Deep dive into Coroutines on JVM
  • 2. There is no magic
  • 4. A toy problem fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Direct style
  • 5. Direct style fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) }
  • 6. Direct style fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Continuation
  • 7. Continuation-Passing Style fun postItem(item: Item) { requestToken { token -> val post = createPost(token, item) processPost(post) } } Continuation CPS == Callbacks
  • 8. Continuation-Passing Style fun postItem(item: Item) { requestToken { token -> createPost(token, item) { post -> processPost(post) } } }
  • 9. Coroutines Direct Style suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) }
  • 10. How does it work? Behind the scenes
  • 11. Kotlin suspending functions Kotlin suspend fun createPost(token: Token, item: Item): Post { … }
  • 12. CPS Transformation Java/JVM suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … }
  • 13. CPS Transformation callback Java/JVM suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … }
  • 14. Continuation suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … } interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 15. Continuation suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … } interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 16. Continuation suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … } interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 17. Continuation suspend fun createPost(token: Token, item: Item): Post { … } Object createPost(Token token, Item item, Continuation<Post> cont) { … } interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 18. 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: CoroutineContext fun resume(value: T) fun resumeWithException(exception: Throwable) }
  • 20. Direct code suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) }
  • 21. Continuations suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Initial continuation
  • 22. Continuations suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Continuation
  • 23. Continuations suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Continuation Convert to CPS?
  • 24. Callbacks? fun postItem(item: Item) { requestToken { token -> createPost(token, item) { post -> processPost(post) } } }
  • 25. Labels suspend fun postItem(item: Item) { // LABEL 0 val token = requestToken() // LABEL 1 val post = createPost(token, item) // LABEL 2 processPost(post) }
  • 26. Labels suspend fun postItem(item: Item) { switch (label) { case 0: val token = requestToken() case 1: val post = createPost(token, item) case 2: processPost(post) } }
  • 27. 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
  • 28. 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
  • 29. fun postItem(item: Item, cont: Continuation) { val sm = … switch (sm.label) { case 0: sm.item = item sm.label = 1 requestToken(sm) case 1: createPost(token, item, sm) case 2: processPost(post) } } Save state
  • 30. fun postItem(item: Item, cont: Continuation) { val sm = object : CoroutineImpl { … } switch (sm.label) { case 0: sm.item = item sm.label = 1 requestToken(sm) case 1: createPost(token, item, sm) case 2: processPost(post) } } Callback State Machine as Continuation
  • 31. fun postItem(item: Item, cont: Continuation) { val sm = object : CoroutineImpl { fun resume(…) { postItem(null, this) } } switch (sm.label) { case 0: sm.item = item sm.label = 1 requestToken(sm) case 1: createPost(token, item, sm) … } Callback
  • 32. 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 = item sm.label = 1 requestToken(sm) case 1: createPost(token, item, sm) … } Callback
  • 33. fun postItem(item: Item, cont: Continuation) { val sm = … switch (sm.label) { case 0: sm.item = item sm.label = 1 requestToken(sm) case 1: val item = sm.item val token = sm.result as Token sm.label = 2 createPost(token, item, sm) … } Restore state
  • 34. fun postItem(item: Item, cont: Continuation) { val sm = … switch (sm.label) { case 0: sm.item = item sm.label = 1 requestToken(sm) case 1: val item = sm.item val token = sm.result as Token sm.label = 2 createPost(token, item, sm) … } Continue
  • 35. 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) }
  • 36. 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
  • 37. State Machine vs Callbacks suspend 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
  • 38. 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
  • 40. Zoo of futures on JVM
  • 41. interface Service { fun createPost(token: Token, item: Item): Call<Post> }
  • 42. interface Service { fun createPost(token: Token, item: Item): Call<Post> } suspend fun createPost(token: Token, item: Item): Post = serviceInstance.createPost(token, item).await()
  • 43. suspend fun <T> Call<T>.await(): T { … }
  • 44. Callbacks everywhere suspend 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 } }) }
  • 45. 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) } }) }
  • 46. suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T
  • 47. suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T Regular function Inspired by call/cc from Scheme
  • 48. Install callback 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) } }) }
  • 49. Install callback 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) } }) }
  • 50. Analyze response 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) } }) }
  • 51. Analyze response 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) } }) } That’s all
  • 54. What thread it resumes on? suspend fun postItem(item: Item) { val token = requestToken() val post = createPost(token, item) processPost(post) } Continuation It depends!
  • 55. What thread it resumes on? fun postItem(item: Item) { launch(UI) { val token = requestToken() val post = createPost(token, item) processPost(post) } } Continuation
  • 56. Continuation Interceptor interface ContinuationInterceptor : CoroutineContext.Element { companion object Key : CoroutineContext.Key<ContinuationInterceptor> fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> }
  • 57. Continuation Interceptor interface ContinuationInterceptor : CoroutineContext.Element { companion object Key : CoroutineContext.Key<ContinuationInterceptor> fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> }
  • 58. Continuation Interceptor interface ContinuationInterceptor : CoroutineContext.Element { companion object Key : CoroutineContext.Key<ContinuationInterceptor> fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> }
  • 59. 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
  • 61. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> Coroutine builder
  • 62. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> A regular function
  • 63. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T>
  • 64. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> suspending lambda
  • 65. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> { val future = CompletableFuture<T>() block.startCoroutine(…) return future }
  • 66. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> { val future = CompletableFuture<T>() block.startCoroutine(…) return future }
  • 67. fun <T> future( context: CoroutineContext = DefaultDispatcher, block: suspend () -> T ): CompletableFuture<T> { val future = CompletableFuture<T>() block.startCoroutine(completion = object : Continuation<T> { … }) return future }
  • 68. 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 }
  • 69. 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!
  • 71. Launch coroutine builder fun launch( context: CoroutineContext = DefaultDispatcher, block: suspend () -> Unit ): Job { … }
  • 72. Launching coroutine val job = launch { … }
  • 73. val job = launch { … } job.join()
  • 74. val job = launch { … } job.join() job.cancel()
  • 75. Job interface Job : CoroutineContext.Element { companion object Key : CoroutineContext.Key<Job> … }
  • 76. Using coroutine context launch { val job = coroutineContext[Job]!! … }
  • 77. Using coroutine context launch { val job = coroutineContext[Job]!! val interceptor = coroutineContext[CoroutineInterceptor]!! … }
  • 82. Cooperative cancellation launch { while (true) { delay(…) … } }
  • 83. Cancellable suspension suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont -> enqueue(…) }
  • 84. Cancellable continuation suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> -> enqueue(…) }
  • 85. Completion handler suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> -> enqueue(…) cont.invokeOnCompletion { this@await.cancel() } }
  • 86. Completion handler suspend fun <T> Call<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> -> enqueue(…) cont.invokeOnCompletion { this@await.cancel() } }
  • 90. Example fun 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) } } }
  • 91. Main coroutine fun 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) } } }
  • 92. Channel fun 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) } } }
  • 93. Launch fun 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
  • 94. Coroutine body fun 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!
  • 95. Send fun 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) } } }
  • 96. Close fun 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) } } }
  • 97. Receive for loop fun 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) } } }
  • 98. Demo
  • 99. Actors The other way to look at CSP
  • 100. The choice Named channels Named coroutines Actor == named coroutine & inbox channel
  • 101. Example fun 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() } }
  • 102. Actor coroutine builder fun 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() } }
  • 103. Actor body fun 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!
  • 104. Interacting with an actor fun 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() } }
  • 106. Guide to kotlinx.coroutines by 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
  • 107. #kotlinconf17 relizarov elizarov at JetBrains Roman Elizarov Thank you Any questions?