Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Kotlin Coroutine

Introduction to Kotlin Coroutine

This talk introduces Kotlin Coroutine, which was a big feature of Kotlin 1.1.

Kotlin coroutine is a suspendable computation. It empowers programmers in some use cases such as async/await, generator.

The talk describes what Kotlin coroutine is and explains suspendCoroutine method behind it.

Reference:
- https://kotlinlang.org/docs/reference/coroutines.html
- https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#use-cases
- https://github.com/Kotlin/kotlin-coroutines

- Introduction to Kotlin Coroutine
https://vimeo.com/222499934
slides: https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines
- Guide to kotlinx.coroutines by example

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

Hiroshi Kurokawa

October 27, 2017
Tweet

More Decks by Hiroshi Kurokawa

Other Decks in Technology

Transcript

  1. INTRODUCTION TO KOTLIN
    COROUTINE
    SHIBUYA.APK #19
    2017.10.27
    HIROSHI KUROKAWA

    FABLIC, INC.

    View full-size slide

  2. WHAT’S COROUTINE?
    A coroutine can be thought of as an instance of
    suspendable computation
    i.e. the one that can suspend at some points and later
    resume execution possibly on another thread.
    https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#use-cases

    View full-size slide

  3. THREAD-BLOCKING CODE SAMPLE
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    fun composeRequest(): Request = …
    fun makeRequest(request: Request): Result = …
    main
    composeRequest makeRequest
    If it takes a long time?
    If it takes a long time?

    View full-size slide

  4. THREAD-BLOCKING CODE SAMPLE
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    fun composeRequest(): Request = …
    fun makeRequest(request: Request): Result = …
    main
    composeRequest makeRequest
    If it takes a long time?
    If it takes a long time?
    The thread is blocked!

    View full-size slide

  5. SUSPEND TO THE RESCUE
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    suspend fun composeRequest(): Request = …
    suspend fun makeRequest(request: Request): Result = …
    1
    2
    ‣ The code suspends at the suspension points
    ‣ The code resumes when the return value is ready

    View full-size slide

  6. SUSPEND TO THE RESCUE
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    suspend fun composeRequest(): Request = …
    suspend fun makeRequest(request: Request): Result = …
    1
    2
    main
    composeRequest makeRequest
    main main
    1 2

    View full-size slide

  7. SUSPEND TO THE RESCUE
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    suspend fun composeRequest(): Request = …
    suspend fun makeRequest(request: Request): Result = …
    1
    2
    main
    composeRequest makeRequest
    main main
    1 2
    The thread is not blocked!

    View full-size slide

  8. CODE CAN BE WRITTEN IN A REGULAR STYLE
    try {
    for (req in list) makeRequest(req)
    } catch (e: Exception) {

    }
    loop
    exception handling

    View full-size slide

  9. CAVEAT
    ‣ “Kotlin suspending functions are designed to
    imitate sequential behaviour by default”,

    Roman Elizarov (https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines)
    ‣ Concurrency has to be explicit

    View full-size slide

  10. Applications

    View full-size slide

  11. val first = loadImageAsync("green")
    val second = loadImageAsync("red")
    overlay(first.await(), second.await())
    fun loadImageAsync(name: String) = async { … }
    ASYNC/AWAIT
    1 2

    View full-size slide

  12. val first = loadImageAsync("green")
    val second = loadImageAsync("red")
    overlay(first.await(), second.await())
    fun loadImageAsync(name: String) = async { … }
    ASYNC/AWAIT
    1 2
    main
    loadImageAsync
    main main
    2
    loadImageAsync
    1

    View full-size slide

  13. Coroutine under the hood "

    View full-size slide

  14. SUSPEND COROUTINE
    suspend fun suspendCoroutine(
    block: (Continuation) -> Unit
    ): T
    ‣ When the method is called, it suspends the
    current coroutine
    ‣ The coroutine is resumed when resume() is called
    on the passed continuation
    Scheme call/cc style!

    View full-size slide

  15. SUSPEND COROUTINE
    suspendCoroutine { cont: Continuation ->
    doLongTask { result, exception ->
    if (exception == null)
    cont.resume(result)
    else
    cont.resumeWithException(exception)
    }
    }
    fun doLongTask(cb: (T, Throwable) -> Unit) {
    }
    suspend fun suspendCoroutine(
    block: (Continuation) -> Unit
    ): T

    View full-size slide

  16. SUSPEND COROUTINE
    suspend fun doLongTaskSuspend() =
    suspendCoroutine { cont: Continuation ->
    doLongTask { result, exception ->
    if (exception == null)
    cont.resume(result)
    else
    cont.resumeWithException(exception)
    䠼}
    䠼}
    result = doLongTaskSuspend()

    // do something with the result

    View full-size slide

  17. What is continuation?

    View full-size slide

  18. CONTINUATION
    val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    1
    2

    View full-size slide

  19. val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    CONTINUATION
    1
    2
    Continuation

    passed to (1)

    View full-size slide

  20. val request = composeRequest()
    val post = makeRequest(request)
    parsePost(post)
    CONTINUATION
    1
    2
    Continuation

    passed to (2)
    No deep stacks and light-weight $
    ‣ Kotlin builds a state machine for each coroutine
    ‣ A suspension point just adds a state to the state
    machine

    View full-size slide

  21. COROUTINE BUILDER
    ‣ Suspending function only can be called from a
    suspending function or a coroutine
    ‣ Use coroutine builders to call suspending
    functions from a regular function
    ‣ launch
    ‣ runBlocking
    ‣ async

    View full-size slide

  22. COROUTINE BUILDER
    fun postItem(item: Item) {
    launch(CommonPool) {
    val token = preparePost()
    val post = submitPost(token, item)
    processPost(post)
    }
    }

    View full-size slide

  23. WRAP UP
    ‣ Coroutine is like a light-weight thread
    ‣ Can be suspended/resumed
    ‣ async/await, generator, channel is just library built on that

    View full-size slide

  24. REFERENCE
    ‣ https://kotlinlang.org/docs/reference/
    coroutines.html
    ‣ https://github.com/Kotlin/kotlin-coroutines

    View full-size slide