158
Asynchronous Programming with Kotlin Coroutines Presented at QCon Beijing, 2018 /Roman Elizarov @ JetBrains

Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

AsynchronousProgrammingwithKotlin Coroutines

PresentedatQCon Beijing,2018/RomanElizarov@JetBrains

Page 2: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Speaker:RomanElizarov

• 17+yearsexperience• Previouslydevelopedhigh-perftradingsoftware@Devexperts• Teachconcurrent&[email protected]• Chiefjudge@NorthernEurasiaContest/ACMICPC• NowteamleadinKotlinLibraries@JetBrains

Page 3: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Pragmatic.Concise.Modern.InteroperablewithJava.

Page 4: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

AsynchronousProgramming

Page 5: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howdowewritecodethatwaitsforsomethingmostofthetime?

Page 6: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

AtoyproblemKotlin fun requestToken(): Token {

// makes request for a token & waitsreturn token // returns result when received

}

1

Page 7: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun requestToken(): Token { … }fun createPost(token: Token, item: Item): Post {

// sends item to the server & waits return post // returns resulting post

}

AtoyproblemKotlin

2

Page 8: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun requestToken(): Token { … }fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) {

// does some local processing of result}

AtoyproblemKotlin

3

Page 9: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun requestToken(): Token { … }fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

AtoyproblemKotlin

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

123

Canbedonewiththreads!

Page 10: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun requestToken(): Token {// makes request for a token // blocks the thread waiting for resultreturn token // returns result when received

}fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

Threads

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Isanythingwrongwithit?

Page 11: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howmanythreadswecanhave?

100�

Page 12: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howmanythreadswecanhave?

1000�

Page 13: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howmanythreadswecanhave?

10000�

Page 14: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howmanythreadswecanhave?

100000�

Page 15: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CallbackstotherescueSortof…

Page 16: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:beforefun requestToken(): Token {

// makes request for a token & waitsreturn token // returns result when received

}

1

Page 17: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:afterfun requestTokenAsync(cb: (Token) -> Unit) {

// makes request for a token, invokes callback when done// returns immediately

}

1callback

Page 18: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:beforefun requestTokenAsync(cb: (Token) -> Unit) { … }fun createPost(token: Token, item: Item): Post {

// sends item to the server & waits return post // returns resulting post

}

2

Page 19: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:afterfun requestTokenAsync(cb: (Token) -> Unit) { … }fun createPostAsync(token: Token, item: Item,

cb: (Post) -> Unit) {// sends item to the server, invokes callback when done// returns immediately

}

2callback

Page 20: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:beforefun requestTokenAsync(cb: (Token) -> Unit) { … }fun createPostAsync(token: Token, item: Item,

cb: (Post) -> Unit) { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Page 21: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbacks:afterfun requestTokenAsync(cb: (Token) -> Unit) { … }fun createPostAsync(token: Token, item: Item,

cb: (Post) -> Unit) { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {requestTokenAsync { token ->

createPostAsync(token, item) { post ->processPost(post)

}}

} aka“callbackhell”

Thisissimplified. Handlingexceptionsmakesitarealmess

Page 22: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures/Promises/RxtotherescueSortof…

Page 23: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:beforefun requestTokenAsync(cb: (Token) -> Unit) {

// makes request for a token, invokes callback when done// returns immediately

}

1

Page 24: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:afterfun requestTokenAsync(): Promise<Token> {

// makes request for a token// returns promise for a future result immediately

}

1future

Page 25: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:beforefun requestTokenAsync(): Promise<Token> { … }fun createPostAsync(token: Token, item: Item,

cb: (Post) -> Unit) {// sends item to the server, invokes callback when done// returns immediately

}

2

Page 26: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:afterfun requestTokenAsync(): Promise<Token> { … }fun createPostAsync(token: Token, item: Item): Promise<Post> {

// sends item to the server // returns promise for a future result immediately

}

future2

Page 27: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:beforefun requestTokenAsync(): Promise<Token> { … }fun createPostAsync(token: Token, item: Item): Promise<Post> …fun processPost(post: Post) { … }

fun postItem(item: Item) {requestTokenAsync { token ->

createPostAsync(token, item) { post ->processPost(post)

}}

}

Page 28: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:afterfun requestTokenAsync(): Promise<Token> { … }fun createPostAsync(token: Token, item: Item): Promise<Post> …fun processPost(post: Post) { … }

fun postItem(item: Item) { requestTokenAsync() .thenCompose { token -> createPostAsync(token, item) } .thenAccept { post -> processPost(post) }}

Composable &propagatesexceptions

Nonestingindentation

Page 29: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Futures:afterfun requestTokenAsync(): Promise<Token> { … }fun createPostAsync(token: Token, item: Item): Promise<Post> …fun processPost(post: Post) { … }

fun postItem(item: Item) { requestTokenAsync() .thenCompose { token -> createPostAsync(token, item) } .thenAccept { post -> processPost(post) }}

Butallthosecombinators…

Page 30: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

KotlincoroutinestotherescueLet’sgetreal

Page 31: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:beforefun requestTokenAsync(): Promise<Token> {

// makes request for a token// returns promise for a future result immediately

}

1

Page 32: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:aftersuspend fun requestToken(): Token {

// makes request for a token & suspendsreturn token // returns result when received

}

1naturalsignature

Page 33: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:beforesuspend fun requestToken(): Token { … }fun createPostAsync(token: Token, item: Item): Promise<Post> {

// sends item to the server // returns promise for a future result immediately

}

2

Page 34: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:aftersuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post {

// sends item to the server & suspendsreturn post // returns result when received

}

2naturalsignature

Page 35: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:beforesuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) { requestTokenAsync() .thenCompose { token -> createPostAsync(token, item) } .thenAccept { post -> processPost(post) }}

Page 36: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:aftersuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Page 37: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:aftersuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Likeregular code

Page 38: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutines:aftersuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

suspensionpoints

Page 39: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

• Regularloops

Bonusfeatures

for ((token, item) in list) {createPost(token, item)

}

Page 40: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

• Regularexceptionhanding

Bonusfeatures

try { createPost(token, item)

} catch (e: BadTokenException) { …

}

Page 41: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

• Regularhigher-orderfunctions

• forEach,let,apply,repeat,filter,map,use,etc

Bonusfeatures

file.readLines().forEach { line ->createPost(token, line.toItem())

}

Page 42: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

• Customhigher-orderfunctions

Bonusfeatures

val post = retryIO {createPost(token, item)

}

Everythinglikeinblockingcode

Page 43: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Howdoesitwork?Aquickpeekbehindthescenes

Page 44: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctions

callback

Kotlin

Java/JVM

suspend fun createPost(token: Token, item: Item): Post { … }

Object createPost(Token token, Item item, Continuation<Post> cont) { … }

Page 45: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctions

callback

Kotlin

Java/JVM

Continuationisagenericcallbackinterface

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 46: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctions

callback

Kotlin

Java/JVM

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 47: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctions

callback

Kotlin

Java/JVM

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 48: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctions

callback

Kotlin

Java/JVM

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 49: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CodewithsuspensionpointsKotlin

Java/JVMCompilestostatemachine(simplifiedcodeshown)

val token = requestToken()val post = createPost(token, item)processPost(post)

switch (cont.label) { case 0: cont.label = 1; requestToken(cont); break; case 1: Token token = (Token) prevResult; cont.label = 2; createPost(token, item, cont); break; case 2: Post post = (Post) prevResult; processPost(post); break;}

Page 50: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CodewithsuspensionpointsKotlin

Java/JVM

val token = requestToken()val post = createPost(token, item)processPost(post)

switch (cont.label) { case 0: cont.label = 1; requestToken(cont); break; case 1: Token token = (Token) prevResult; cont.label = 2; createPost(token, item, cont); break; case 2: Post post = (Post) prevResult; processPost(post); break;}

Page 51: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

IntegrationZoooffuturesonJVM

Page 52: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

interface Service {fun createPost(token: Token, item: Item): Call<Post>

}

Retrofitasync

Page 53: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

interface Service {fun createPost(token: Token, item: Item): Call<Post>

}

suspend fun createPost(token: Token, item: Item): Post =serviceInstance.createPost(token, item).await()

naturalsignature

Page 54: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

interface Service {fun createPost(token: Token, item: Item): Call<Post>

}

suspend fun createPost(token: Token, item: Item): Post =serviceInstance.createPost(token, item).await()

Suspendingextensionfunctionfromintegrationlibrary

Page 55: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

suspend fun <T> Call<T>.await(): T {…

}

Page 56: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Callbackseverywhere

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 } })}

Page 57: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

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 58: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T

Page 59: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T

Page 60: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

suspend fun <T> suspendCoroutine(block: (Continuation<T>) -> Unit): T

Regularfunction

Inspiredbycall/cc fromScheme

Page 61: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

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 62: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Installcallback

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 63: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Installcallback

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 64: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Analyzeresponse

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 65: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Analyzeresponse

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’sall

Page 66: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Out-of-theboxintegrations

kotlinx-coroutines-core

jdk8

guava

nio

reactor

rx1

rx2

Page 67: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CoroutinebuildersHowcanwestartacoroutine?

Page 68: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Page 69: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Page 70: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Error: Suspendfunction'requestToken'shouldbecalledonlyfromacoroutineoranothersuspendfunction

Page 71: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Cansuspend execution

Page 72: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Cansuspend executionAregularfunctioncannot

Page 73: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Coroutinesrevisitedsuspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

Cansuspend executionAregularfunctioncannot

Onecannotsimplyinvokeasuspendingfunction

Page 74: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Launch

fun postItem(item: Item) {launch {

val token = requestToken()val post = createPost(token, item)processPost(post)

}}

coroutinebuilder

Page 75: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun postItem(item: Item) {launch {

val token = requestToken()val post = createPost(token, item)processPost(post)

}}

Fireandforget!

Returnsimmediately,coroutineworksinbackgroundthreadpool

Page 76: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun postItem(item: Item) {launch {

val token = requestToken()val post = createPost(token, item)processPost(post)

}}

Page 77: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun postItem(item: Item) {launch(UI) {

val token = requestToken()val post = createPost(token, item)processPost(post)

}}

UIContext

Justspecifythecontext

Page 78: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun postItem(item: Item) {launch(UI) {

val token = requestToken()val post = createPost(token, item)processPost(post)

}}

UIContext

AnditgetsexecutedonUIthread

Page 79: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Where’sthemagicoflaunch?

Page 80: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun launch(context: CoroutineContext = DefaultDispatcher,block: suspend () -> Unit

): Job { … }

Aregularfunction

Page 81: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun launch(context: CoroutineContext = DefaultDispatcher,block: suspend () -> Unit

): Job { … } suspending lambda

Page 82: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun launch(context: CoroutineContext = DefaultDispatcher,block: suspend () -> Unit

): Job { … }

Page 83: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

async /awaitTheclassicapproach

Page 84: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlin-way

suspend fun postItem(item: Item) {val token = requestToken()val post = createPost(token, item)processPost(post)

}

suspend fun requestToken(): Token { … }suspend fun createPost(token: Token, item: Item): Post { … }fun processPost(post: Post) { … }

Kotlin

Page 85: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

async Task postItem(Item item) { var token = await requestToken(); var post = await createPost(token, item); processPost(post);

}

Classic-way

C#approachtothesameproblem(alsoPython,TS,Dart,comingtoJS)

async Task<Token> requestToken() { … }async Task<Post> createPost(Token token, Item item) { … }void processPost(Post post) { … }

C#

Page 86: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

async Task postItem(Item item) { var token = await requestToken(); var post = await createPost(token, item); processPost(post);

}

Classic-way

markwithasync

async Task<Token> requestToken() { … }async Task<Post> createPost(Token token, Item item) { … }void processPost(Post post) { … }

C#

Page 87: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

async Task postItem(Item item) { var token = await requestToken(); var post = await createPost(token, item); processPost(post);

}

Classic-way

useawaittosuspend

async Task<Token> requestToken() { … }async Task<Post> createPost(Token token, Item item) { … }void processPost(Post post) { … }

C#

Page 88: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

async Task postItem(Item item) { var token = await requestToken(); var post = await createPost(token, item); processPost(post);

}

Classic-way

returnsafuture

async Task<Token> requestToken() { … }async Task<Post> createPost(Token token, Item item) { … }void processPost(Post post) { … }

C#

Page 89: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Whynoawait keywordinKotlin?

Theproblemwithasync

requestToken() VALID –>producesTask<Token>

await requestToken() VALID –>producesToken

concurrentbehavior

sequentialbehavior

C#

C#

default

ConcurrencyishardConcurrencyhastobeexplicit

Page 90: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinsuspendingfunctionsaredesignedtoimitatesequential behavior

bydefault

ConcurrencyishardConcurrencyhastobeexplicit

Page 91: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

KotlinapproachtoasyncConcurrencywhereyouneed it

Page 92: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Use-caseforasync

async Task<Image> loadImageAsync(String name) { … } C#

Page 93: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Use-caseforasync

var promise1 = loadImageAsync(name1);var promise2 = loadImageAsync(name2);

async Task<Image> loadImageAsync(String name) { … }

Startmultipleoperationsconcurrently

C#

Page 94: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Use-caseforasync

var promise1 = loadImageAsync(name1);var promise2 = loadImageAsync(name2);

var image1 = await promise1;var image2 = await promise2;

async Task<Image> loadImageAsync(String name) { … }

andthenwaitforthem

C#

Page 95: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Use-caseforasync

var result = combineImages(image1, image2);

var promise1 = loadImageAsync(name1);var promise2 = loadImageAsync(name2);

var image1 = await promise1;var image2 = await promise2;

async Task<Image> loadImageAsync(String name) { … } C#

Page 96: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

Kotlin

Page 97: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

Aregularfunction

Kotlin

Page 98: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

Kotlin’s futuretype

Kotlin

Page 99: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

async coroutinebuilder

Kotlin

Page 100: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

val deferred1 = loadImageAsync(name1)val deferred2 = loadImageAsync(name2)

Startmultipleoperationsconcurrently

Kotlin

Page 101: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

val deferred1 = loadImageAsync(name1)val deferred2 = loadImageAsync(name2)

val image1 = deferred1.await()val image2 = deferred2.await() andthenwaitforthem

awaitfunction

Suspendsuntildeferrediscomplete

Kotlin

Page 102: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinasync function

fun loadImageAsync(name: String): Deferred<Image> = async { … }

val deferred1 = loadImageAsync(name1)val deferred2 = loadImageAsync(name2)

val image1 = deferred1.await()val image2 = deferred2.await()

val result = combineImages(image1, image2)

Kotlin

Page 103: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Usingasync functionwhenneeded

suspend fun loadImage(name: String): Image { … }

Isdefinedassuspendingfunction,notasync

Page 104: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Usingasync functionwhenneeded

suspend fun loadImage(name: String): Image { … }

suspend fun loadAndCombine(name1: String, name2: String): Image { val deferred1 = async { loadImage(name1) }val deferred2 = async { loadImage(name2) }return combineImages(deferred1.await(), deferred2.await())

}

Page 105: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Usingasync functionwhenneeded

suspend fun loadImage(name: String): Image { … }

suspend fun loadAndCombine(name1: String, name2: String): Image { val deferred1 = async { loadImage(name1) }val deferred2 = async { loadImage(name2) }return combineImages(deferred1.await(), deferred2.await())

}

Page 106: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Usingasync functionwhenneeded

suspend fun loadImage(name: String): Image { … }

suspend fun loadAndCombine(name1: String, name2: String): Image { val deferred1 = async { loadImage(name1) }val deferred2 = async { loadImage(name2) }return combineImages(deferred1.await(), deferred2.await())

}

Page 107: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Usingasync functionwhenneeded

suspend fun loadImage(name: String): Image { … }

suspend fun loadAndCombine(name1: String, name2: String): Image { val deferred1 = async { loadImage(name1) }val deferred2 = async { loadImage(name2) }return combineImages(deferred1.await(), deferred2.await())

}

Page 108: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlinapproachtoasync

requestToken() VALID –>producesToken

async { requestToken() } VALID –>producesDeferred<Token>

sequentialbehavior

concurrentbehavior

Kotlin

Kotlin

default

Page 109: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Whatarecoroutinesconceptually?

Page 110: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Whatarecoroutinesconceptually?Coroutinesarelikevery light-weightthreads

Page 111: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Page 112: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example Thiscoroutinebuilderrunscoroutineinthecontextofinvokerthread

Page 113: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Page 114: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Page 115: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Suspendsfor1second

Page 116: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Wecanjoinajobjustlikeathread

Page 117: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Trythatwith100kthreads!

Prints100kdotsafteroneseconddelay

Page 118: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) = runBlocking<Unit> {val jobs = List(100_000) {

launch {delay(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Page 119: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) {val jobs = List(100_000) {

thread {Thread.sleep(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Page 120: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

fun main(args: Array<String>) {val jobs = List(100_000) {

thread {Thread.sleep(1000L)print(".")

}}jobs.forEach { it.join() }

}

Example

Exceptioninthread"main"java.lang.OutOfMemoryError:unabletocreatenewnativethread

Page 121: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

JavainteropCanweuseKotlincoroutineswithJavacode?

Page 122: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Javainterop

CompletableFuture<Image> loadImageAsync(String name) { … }Java

Page 123: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }

CompletableFuture<Image> loadAndCombineAsync(String name1, String name2)

Java

Imagineimplementing itinJava…

Page 124: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }

CompletableFuture<Image> loadAndCombineAsync(String name1,String name2)

{CompletableFuture<Image> future1 = loadImageAsync(name1);CompletableFuture<Image> future2 = loadImageAsync(name2);return future1.thenCompose(image1 ->

future2.thenCompose(image2 ->CompletableFuture.supplyAsync(() ->

combineImages(image1, image2))));}

Java

Page 125: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }Java

fun loadAndCombineAsync(name1: String, name2: String

): CompletableFuture<Image> =…

Kotlin

Page 126: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }Java

fun loadAndCombineAsync(name1: String, name2: String

): CompletableFuture<Image> =future {

val future1 = loadImageAsync(name1)val future2 = loadImageAsync(name2)combineImages(future1.await(), future2.await())

}

Kotlin

Page 127: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }Java

fun loadAndCombineAsync(name1: String, name2: String

): CompletableFuture<Image> =future {

val future1 = loadImageAsync(name1)val future2 = loadImageAsync(name2)combineImages(future1.await(), future2.await())

}

Kotlinfuturecoroutinebuilder

Page 128: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }Java

fun loadAndCombineAsync(name1: String, name2: String

): CompletableFuture<Image> =future {

val future1 = loadImageAsync(name1)val future2 = loadImageAsync(name2)combineImages(future1.await(), future2.await())

}

Kotlin

Page 129: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

CompletableFuture<Image> loadImageAsync(String name) { … }Java

fun loadAndCombineAsync(name1: String, name2: String

): CompletableFuture<Image> =future {

val future1 = loadImageAsync(name1)val future2 = loadImageAsync(name2)combineImages(future1.await(), future2.await())

}

Kotlin

Page 130: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

BeyondasynchronouscodeKotlin’s approachtogenerate/yield– synchronouscoroutines

Page 131: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci: Sequence<Int> = …

Page 132: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

Page 133: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

println(fibonacci.take(10).toList())

Page 134: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

println(fibonacci.take(10).toList())

>> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Page 135: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

Acoroutinebuilderwithrestrictedsuspension

Page 136: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

AsuspendingfunctioninthescopeofbuildSequence

Page 137: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

println(fibonacci.take(10).toList())

Synchronous

Page 138: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()

Page 139: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next())

Page 140: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next())

Page 141: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next())

Page 142: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next())

Page 143: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1

Page 144: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next())

Page 145: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next())

Page 146: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next())

Page 147: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next())

Page 148: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next())

Page 149: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next()) // 1

Page 150: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Fibonaccisequence

val fibonacci = buildSequence {var cur = 1var next = 1while (true) {

yield(cur) val tmp = cur + nextcur = nextnext = tmp

}}

val iter = fibonacci.iterator()println(iter.next()) // 1println(iter.next()) // 1 etc adinfinum

Page 151: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

LibraryvsLanguageKeepingthecorelanguagesmall

Page 152: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Classicasync

async/awaitgenerate/yield Keywords

Page 153: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlincoroutines

suspend Modifier

Page 154: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlincoroutines

Standardlibrary

Page 155: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Kotlincoroutines

Standardlibrary

kotlinx-coroutines

launch,async,runBlocking,future,delay,

Job,Deferred,etc

http://github.com/kotlin/kotlinx.coroutines

Page 156: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Thereismore

• CommunicatingSequentialProcesses(CSP)Style• ChannelsandActors• Selectionandsynchronization• Jobhierarchiesandcancellation

• LearnmoreinGuidetokotlinx.coroutinesbyexample

• KotlinConf 2018 (3-5Oct)inAmsterdam

Page 157: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts

Thankyou

Anyquestions?

Slidesareavailableatwww.slideshare.net/elizarovemailmetoelizarov atgmail

relizarov

Page 158: Asynchronous Programming with KotlinCoroutines · 2018. 4. 28. · Speaker: Roman Elizarov • 17+ years experience • Previously developed high -perf trading software @ Devexperts