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

Koroutinify ; Lessons learned from applying Cor...

oshai
December 25, 2018

Koroutinify ; Lessons learned from applying Coroutines in Kotlin Backend ; Deep dive into Coroutines

oshai

December 25, 2018
Tweet

More Decks by oshai

Other Decks in Technology

Transcript

  1. Koroutinify Lessons learned from applying Coroutines in Kotlin Backend Deep

    dive into Coroutines Ohad Shai - Software Engineer & Kotlin Advocate @Outbrain https://medium.com/@OhadShai
  2. What we will talk about •A quick recap on coroutines

    •We’ll take a look under the hood •Tips and tricks
  3. Disclaimer • I don’t know all coroutines bits and bytes

    • We will look on coroutines from a *specific* angle - coroutines has more to offer • Some of the things reflects my opinion
  4. Motivation • We want to serve many users by few

    servers • Imagine that we have only one core and one thread for our service • When we suspend, our thread is free to go to serve other users
  5. What is coroutines • Write async code sequentially • Lightweight

    threads • aka callback-hell without the hell
  6. Where does coroutines shines? suspend fun <A> Connection.inTransaction( f: suspend

    (Connection) -> A): A { try { this.sendQuery("BEGIN") val result = f(this) this.sendQuery("COMMIT") return result } catch (e: Throwable) { this.sendQuery("ROLLBACK") throw e } }
  7. Where does coroutines shines? fun <A> Connection.inTransaction( f: (Connection) ->

    CompletableFuture<A>) : CompletableFuture<A> { return this.sendQuery("BEGIN").flatMap { val p = CompletableFuture<A>() f(this).onComplete { ty1 -> sendQuery( if (ty1.isFailure) "ROLLBACK" else "COMMIT") .onComplete { ty2 -> if (ty2.isFailure && ty1.isSuccess) p.failed((ty2 as Failure).exception) else p.complete(ty1) } } p } }
  8. Resume val outcome = current.invokeSuspend(param) if (outcome === COROUTINE_SUSPENDED) return

    current = completion param = outcome Continuation Completion - The parent Continuation invokeSuspend() - The installed callback; the method to return to label - where to return in the method
  9. Resume val outcome = current.invokeSuspend(param) if (outcome === COROUTINE_SUSPENDED) return

    current = completion param = outcome Continuation Completion - The parent Continuation invokeSuspend() - The installed callback; the method to return to label - where to return in the method Repeat until root continuation
  10. What coroutines made of • std-lib support for suspend functions

    • kotlinx.coroutines - a rich library for coroutines developed by JetBrains
  11. What can go wrong? Don’t catch exceptions of await()! https://

    github.com/Kotlin/ kotlinx.coroutines/ issues/763
  12. Scope / Exception and Cancellation • Hierarchy coroutineScope { …

    } • GlobalScope • Live in the application lifetime
  13. Scope / Exception and Cancellation • Hierarchy coroutineScope { …

    } • GlobalScope • Live in the application lifetime • SupervisorJob / Job
  14. Blocking code • Replace with async libs • Use IO

    Dispatcher / dedicated thread pool async(Dispatcher.IO) {…}
  15. @Experimental Status • As of 1.3 coroutines was GA •

    But… https://www.kiwico.com/blog/2016/09/26/10-easy-science-experiments-for-kids/
  16. @Experimental Status • As of 1.3 coroutines was GA •

    But… Many API’s are still experimental https://www.kiwico.com/blog/2016/09/26/10-easy-science-experiments-for-kids/
  17. What’s in it for me? • Use it in your

    micro-service • Find a side use case • Actor / Channels