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

Koroutinify ; Lessons learned from applying Cor...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →
oshai
December 25, 2018

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

oshai

December 25, 2018

Transcript

94 slides
  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

More Decks by oshai

Other Decks in Technology