SlideShare a Scribd company logo
1 of 33
Download to read offline
Current State of
Coroutines
Presented at Kotlin Meetup 11/2017

/Guido Pio Mariotti @ OLX
What is this presentation
about?
• For an in depth introduction to coroutines look at
Introduction to Kotlin Coroutines and Deep Dives into
Coroutines on JVM from Roman Elizarov.

• What offers kotlinx-coroutines.
What are coroutines?
• Light-weight threads, is it correct?
• Instances of suspendable computation!
• Quite an old concept from 1960s.

• Present in multiple languages —> JS, Python, C#

• However, how are implemented is quite different.
What is the goal of
coroutines?
• Make concurrency simple.

• Make concurrent code explicit.
• From

val future : Future<Result> = httpRequest(request)
val result : Result = await httpRequest(request) // await keyword
• To

val future : Deferred<Result> = async { httpRequest(request) }
val result : Result = httpRequest(request)
What experimental means?
KotlinConf Keynote Recap
Even though coroutines are still labeled as an experimental
feature, we’d like to clarify the exact meaning of this status.
Coroutines are fully ready to be used in production, […].
The reason why we keep the experimental status is that it gives us
the ability to iterate on the design. Note that, even if we do make
changes to the API, the current API will remain supported, even
though it will be marked as deprecated, and we will provide the
necessary migration tools. According to our current plans, the
experimental status of coroutines will be removed in Kotlin 1.3.
Current State
• Version - 0.19.3

• kotlinx-coroutines-

• core
• [integration] - jdk8, nio, guava, quasar

• [ui] - android, javafx, swing

• [reactive] - reactive, reactor, rx1, rx2
Building blocks - 1
suspend fun launchAndRepeat() {
launch {
repeat(100_000) {
println("I'm sleeping $it...")
delay(500)
}
}
delay(1300)
}
suspend fun repeatAndLaunch() {
repeat(100_000) {
launch {
print(".")
delay(500)
}
}
delay(1300)
}
Keyword
Building blocks - 2
suspend fun launchAndRepeat() {
launch {
repeat(100_000) {
println("I'm sleeping $it...")
delay(500)
}
}
delay(1300)
}
suspend fun repeatAndLaunch() {
repeat(100_000) {
launch {
print(".")
delay(500)
}
}
delay(1300)
}
Suspending

Function
Suspending

Function
Building blocks - 3
suspend fun launchAndRepeat() {
launch {
repeat(100_000) {
println("I'm sleeping $it...")
delay(500)
}
}
delay(1300)
}
suspend fun repeatAndLaunch() {
repeat(100_000) {
launch {
print(".")
delay(500)
}
}
delay(1300)
}
Coroutine
builder
Coroutine

builder
Building blocks - 4
suspend fun launchAndRepeat() {
launch {
repeat(100_000) {
println("I'm sleeping $it...")
delay(500)
}
}
delay(1300)
}
suspend fun repeatAndLaunch() {
repeat(100_000) {
launch {
print(".")
delay(500)
}
}
delay(1300)
}
Coroutine
Coroutine
kotlinx-coroutines-core
launch
• launch is used to build a Job, a coroutine of which we
are not interested in its result.

• Some useful methods:

• cancel()
• join()
• cancelAndJoin()
• invokeOnJobCompletion(..)
async
• async is used to build a Deferred, a non-blocking
cancellable future.

• Implements Job interface.

• await() is a non-blocking method for collecting the
result of the coroutine.
async - example
fun main(args: Array<String>) = runBlocking {
val sequentialTime = measureTimeMillis {
val twoSquare = getSquareFromServer(2)
val threeSquare = getSquareFromServer(3)
println("2^2 = $twoSquare || 3^2 = $threeSquare")
}
val asyncTime = measureTimeMillis {
val twoSquare = async { getSquareFromServer(2) }
val threeSquare = async { getSquareFromServer(3) }
println("2^2 = ${twoSquare.await()} || 3^2 = ${threeSquare.await()}")
}
println("Sequential time = $sequentialTime ms”) // ~2000ms
println("Async time = $asyncTime ms”) // ~1000ms
}
suspend fun getSquareFromServer(value: Int): Int {
delay(1, TimeUnit.SECONDS) // simulate a non-blocking call to the server
return value * value
}
produce
• produce is used to create a ProducerJob, for streams
of elements production.

• Sends elements inside a channel.

• Channel can be buffered or unbuffered.
produce - example
suspend fun produce_example() {
val dotGenerator = produce(newSingleThreadContext("dot-thread")) {
println("dotGenerator is in thread [${Thread.currentThread().name}]") // working in thread [dot-thread]
while (isActive) {
send(".")
delay(50)
}
}
val dotChannel = dotGenerator.channel
val dotPyramid = produce {
println("dotPyramid starting in thread [${Thread.currentThread().name}]") // [commonPool-worker-n]
(1..10).map {
async(coroutineContext) {
println("[$it] in thread [${Thread.currentThread().name}]") // [commonPool-worker-n]
buildString { (1..it).map { append(dotChannel.receive()) } }
}
}.map { send(it.await()) }
delay(50)
println("dotPyramid ending in thread [${Thread.currentThread().name}]") // [commonPool-worker-n]
}
while (dotPyramid.isActive) {
try {
println(dotPyramid.receive())
} catch (e: ClosedReceiveChannelException) {
println("The pyramid channel has been closed")
}
}
println("Is dotGenerator active? ${dotGenerator.isActive}")
}
actor
• actor produces an ActorJob, that processes a stream of
messages.

• Used to implement the Actor Model.

• An actor is a computational entity that, in response to a message
it receives, can concurrently:

• send a finite number of messages to other actors;

• create a finite number of new actors;

• designate the behavior to be used for the next message it receives.
actor - example
sealed class Http
data class HttpRequest(val request: CompletableDeferred<Int?>) : Http()
data class HttpResponse(val response: Int) : Http()
suspend fun actor_http() {
val httpRandomNumActor = httpActor()
sendPeriodicallyRandomInt(httpRandomNumActor)
(1..10).forEach {
delay(10)
val response = CompletableDeferred<Int?>()
httpRandomNumActor.send(HttpRequest(response))
println("Sent request $it")
println("[$it] --> response ${response.await()}")
}
}
suspend fun httpActor() = actor<Http>(newFixedThreadPoolContext(3, "http-actor")) {
var latestResponse: Int? = null
for (msg in channel) {
when (msg) {
is HttpRequest -> msg.request.complete(latestResponse)
is HttpResponse -> {
latestResponse = msg.response
println("Updated response on [${Thread.currentThread().name}]")
}
}
}
}
private fun sendPeriodicallyRandomInt(httpRandomNum: ActorJob<Http>) {
launch {
while (isActive) {
httpRandomNum.send(HttpResponse(Random().nextInt()))
println("Sent response on [${Thread.currentThread().name}]")
delay(30)
}
}
}
Generators and yield
• Possibility to have Generators using Kotlin Sequence.
• yield() and yieldAll() to suspend the computation.

• Part of Kotlin stdlib.
Generators - example
import kotlin.coroutines.experimental.buildSequence
fun generator() {
fibonacci().take(5) // Lazily evaluated as expected
for (num in fibonacci()) {
if (num == 13) break
}
}
fun fibonacci() = buildSequence {
var prev = 1
println("Current value is $prev")
yield(prev)
var next = 1
while (true) {
println("Current value is $next")
val tmp = next
yield(tmp)
next = prev + tmp
prev = tmp
}
}
Select
• select offers the possibility to choose the first result
returned by two or more suspending functions, that
returns a SelectClause#N.

• Biased on the order of the functions.

• selectUnbiased solves this issue.
Select - example
suspend fun randomNumProducer(id: Int) = produce {
while (isActive) {
send("[${Thread.currentThread().name}] - Produce $id")
val sleep = Random().nextInt(50).toLong()
delay(sleep)
}
}
suspend fun selectBetween(channel1: ReceiveChannel<String>, channel2: ReceiveChannel<String>) {
select<Unit> {
channel1.onReceive {
println(it)
}
channel2.onReceiveOrNull {
println(it ?: "[${Thread.currentThread().name}] - channel is closed")
}
}
}
suspend fun select_example() {
val producer1 = randomNumProducer(1)
val producer2 = randomNumProducer(2)
repeat(5) {
selectBetween(producer1, producer2)
}
producer2.cancel()
repeat(3) {
selectBetween(producer1, producer2)
}
}
What else?
• Non-blocking Mutex.
• Channel, like the one used by actor and produce.

• Suspending function withTimeout,
withTimeoutOrNull and run.
kotlinx-coroutines-ui
What is in there?
• kotlinx-coroutines-android, offers the UI context.

• kotlinx-coroutines-javafx, offers the JavaFx context.

• kotlinx-coroutines-swing, offers the Swing context.
UI - example
fun ui_example() {
launch {
val image = async { loadImage() }
val title = async { loadTitle() }
display(image.await(), title.await())
}
}
suspend fun display(image: Image, title: String) {
run(UI) {
// display on UI thread
}
}
suspend fun loadImage(): Image =
downloadImage() // non-blocking operation for downloading the image
suspend fun loadTitle(): String =
downloadTitle() // non-blocking operation for downloading the title
kotlinx-coroutines-
integration
What is in there?
• kotlinx-coroutines-jdk8, integration with
CompletableFuture.
• kotlinx-coroutines-nio, integration with JDK7+ Async IO.
• kotlinx-coroutines-guava, integration with
ListenableFuture.
• kotlinx-coroutines-quasar, integration with Quasar
library.
CompletableFuture
• The coroutine builder future.

• Extension functions await().

• [!] CompletableFuture should be used only for
interacting with existing libraries that use it, otherwise
prefer Deferred<T>.

• [!!] get() is blocking, await() is not.
CompletableFuture -
example
suspend fun future_example() {
val readString = future(context = newSingleThreadContext("read-string")) {
stringWithDelay()
}
val readString2 = future {
stringWithDelay()
}
println("${readString.await()} - ${readString2.await()}")
}
suspend fun stringWithDelay(): String {
println("Current thread is [${Thread.currentThread().name}]")
delay(10)
println("Current thread is [${Thread.currentThread().name}]")
return "future"
}
kotlinx-coroutines-reactive
• Support for RxJava 1.x and 2.x, Reactor and Reactive
Streams.

• [!] If you’re fine with RxJava than you don’t really need
coroutines.
Recap
• Should you use coroutines in production? YES!!

• Should you use coroutines everywhere? NO!!

• They still relay on OS threads —> if you call blocking
code inside a coroutine, you block the thread on which
the coroutine is running —> Be Careful!!

• They make sense for IO bound tasks, not CPU bound
tasks!!
Resources
• Channel in Kotlin Slack - #coroutines

• KEEP - https://github.com/Kotlin/kotlin-coroutines

• Repository - https://github.com/Kotlin/kotlinx.coroutines

More Related Content

What's hot

Rust-lang
Rust-langRust-lang

What's hot (20)

Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Non blocking io with netty
Non blocking io with nettyNon blocking io with netty
Non blocking io with netty
 
Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
Rust
RustRust
Rust
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)
 
Introducing to Asynchronous Programming
Introducing to Asynchronous  ProgrammingIntroducing to Asynchronous  Programming
Introducing to Asynchronous Programming
 
Introduction to Rust language programming
Introduction to Rust language programmingIntroduction to Rust language programming
Introduction to Rust language programming
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
 
GPars For Beginners
GPars For BeginnersGPars For Beginners
GPars For Beginners
 
Metaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common LispMetaprogramming and Reflection in Common Lisp
Metaprogramming and Reflection in Common Lisp
 
sizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may mattersizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may matter
 

Similar to Current State of Coroutines

Similar to Current State of Coroutines (20)

Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
 
Kotlin Coroutines - the new async
Kotlin Coroutines - the new asyncKotlin Coroutines - the new async
Kotlin Coroutines - the new async
 
Exploring Kotlin
Exploring KotlinExploring Kotlin
Exploring Kotlin
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
Loom me up Scotty! Project Loom - What's in it for Me?
Loom me up Scotty!  Project Loom - What's in it for Me?Loom me up Scotty!  Project Loom - What's in it for Me?
Loom me up Scotty! Project Loom - What's in it for Me?
 
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
 
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
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
 
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
 
Programação assíncrona utilizando Coroutines
Programação assíncrona utilizando CoroutinesProgramação assíncrona utilizando Coroutines
Programação assíncrona utilizando Coroutines
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Akka
AkkaAkka
Akka
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 

Current State of Coroutines

  • 1. Current State of Coroutines Presented at Kotlin Meetup 11/2017 /Guido Pio Mariotti @ OLX
  • 2. What is this presentation about? • For an in depth introduction to coroutines look at Introduction to Kotlin Coroutines and Deep Dives into Coroutines on JVM from Roman Elizarov. • What offers kotlinx-coroutines.
  • 3. What are coroutines? • Light-weight threads, is it correct? • Instances of suspendable computation! • Quite an old concept from 1960s. • Present in multiple languages —> JS, Python, C# • However, how are implemented is quite different.
  • 4. What is the goal of coroutines? • Make concurrency simple. • Make concurrent code explicit. • From val future : Future<Result> = httpRequest(request) val result : Result = await httpRequest(request) // await keyword • To val future : Deferred<Result> = async { httpRequest(request) } val result : Result = httpRequest(request)
  • 5. What experimental means? KotlinConf Keynote Recap Even though coroutines are still labeled as an experimental feature, we’d like to clarify the exact meaning of this status. Coroutines are fully ready to be used in production, […]. The reason why we keep the experimental status is that it gives us the ability to iterate on the design. Note that, even if we do make changes to the API, the current API will remain supported, even though it will be marked as deprecated, and we will provide the necessary migration tools. According to our current plans, the experimental status of coroutines will be removed in Kotlin 1.3.
  • 6. Current State • Version - 0.19.3 • kotlinx-coroutines- • core • [integration] - jdk8, nio, guava, quasar • [ui] - android, javafx, swing • [reactive] - reactive, reactor, rx1, rx2
  • 7. Building blocks - 1 suspend fun launchAndRepeat() { launch { repeat(100_000) { println("I'm sleeping $it...") delay(500) } } delay(1300) } suspend fun repeatAndLaunch() { repeat(100_000) { launch { print(".") delay(500) } } delay(1300) } Keyword
  • 8. Building blocks - 2 suspend fun launchAndRepeat() { launch { repeat(100_000) { println("I'm sleeping $it...") delay(500) } } delay(1300) } suspend fun repeatAndLaunch() { repeat(100_000) { launch { print(".") delay(500) } } delay(1300) } Suspending
 Function Suspending
 Function
  • 9. Building blocks - 3 suspend fun launchAndRepeat() { launch { repeat(100_000) { println("I'm sleeping $it...") delay(500) } } delay(1300) } suspend fun repeatAndLaunch() { repeat(100_000) { launch { print(".") delay(500) } } delay(1300) } Coroutine builder Coroutine
 builder
  • 10. Building blocks - 4 suspend fun launchAndRepeat() { launch { repeat(100_000) { println("I'm sleeping $it...") delay(500) } } delay(1300) } suspend fun repeatAndLaunch() { repeat(100_000) { launch { print(".") delay(500) } } delay(1300) } Coroutine Coroutine
  • 12. launch • launch is used to build a Job, a coroutine of which we are not interested in its result. • Some useful methods: • cancel() • join() • cancelAndJoin() • invokeOnJobCompletion(..)
  • 13. async • async is used to build a Deferred, a non-blocking cancellable future. • Implements Job interface. • await() is a non-blocking method for collecting the result of the coroutine.
  • 14. async - example fun main(args: Array<String>) = runBlocking { val sequentialTime = measureTimeMillis { val twoSquare = getSquareFromServer(2) val threeSquare = getSquareFromServer(3) println("2^2 = $twoSquare || 3^2 = $threeSquare") } val asyncTime = measureTimeMillis { val twoSquare = async { getSquareFromServer(2) } val threeSquare = async { getSquareFromServer(3) } println("2^2 = ${twoSquare.await()} || 3^2 = ${threeSquare.await()}") } println("Sequential time = $sequentialTime ms”) // ~2000ms println("Async time = $asyncTime ms”) // ~1000ms } suspend fun getSquareFromServer(value: Int): Int { delay(1, TimeUnit.SECONDS) // simulate a non-blocking call to the server return value * value }
  • 15. produce • produce is used to create a ProducerJob, for streams of elements production. • Sends elements inside a channel. • Channel can be buffered or unbuffered.
  • 16. produce - example suspend fun produce_example() { val dotGenerator = produce(newSingleThreadContext("dot-thread")) { println("dotGenerator is in thread [${Thread.currentThread().name}]") // working in thread [dot-thread] while (isActive) { send(".") delay(50) } } val dotChannel = dotGenerator.channel val dotPyramid = produce { println("dotPyramid starting in thread [${Thread.currentThread().name}]") // [commonPool-worker-n] (1..10).map { async(coroutineContext) { println("[$it] in thread [${Thread.currentThread().name}]") // [commonPool-worker-n] buildString { (1..it).map { append(dotChannel.receive()) } } } }.map { send(it.await()) } delay(50) println("dotPyramid ending in thread [${Thread.currentThread().name}]") // [commonPool-worker-n] } while (dotPyramid.isActive) { try { println(dotPyramid.receive()) } catch (e: ClosedReceiveChannelException) { println("The pyramid channel has been closed") } } println("Is dotGenerator active? ${dotGenerator.isActive}") }
  • 17. actor • actor produces an ActorJob, that processes a stream of messages. • Used to implement the Actor Model. • An actor is a computational entity that, in response to a message it receives, can concurrently: • send a finite number of messages to other actors; • create a finite number of new actors; • designate the behavior to be used for the next message it receives.
  • 18. actor - example sealed class Http data class HttpRequest(val request: CompletableDeferred<Int?>) : Http() data class HttpResponse(val response: Int) : Http() suspend fun actor_http() { val httpRandomNumActor = httpActor() sendPeriodicallyRandomInt(httpRandomNumActor) (1..10).forEach { delay(10) val response = CompletableDeferred<Int?>() httpRandomNumActor.send(HttpRequest(response)) println("Sent request $it") println("[$it] --> response ${response.await()}") } } suspend fun httpActor() = actor<Http>(newFixedThreadPoolContext(3, "http-actor")) { var latestResponse: Int? = null for (msg in channel) { when (msg) { is HttpRequest -> msg.request.complete(latestResponse) is HttpResponse -> { latestResponse = msg.response println("Updated response on [${Thread.currentThread().name}]") } } } } private fun sendPeriodicallyRandomInt(httpRandomNum: ActorJob<Http>) { launch { while (isActive) { httpRandomNum.send(HttpResponse(Random().nextInt())) println("Sent response on [${Thread.currentThread().name}]") delay(30) } } }
  • 19. Generators and yield • Possibility to have Generators using Kotlin Sequence. • yield() and yieldAll() to suspend the computation. • Part of Kotlin stdlib.
  • 20. Generators - example import kotlin.coroutines.experimental.buildSequence fun generator() { fibonacci().take(5) // Lazily evaluated as expected for (num in fibonacci()) { if (num == 13) break } } fun fibonacci() = buildSequence { var prev = 1 println("Current value is $prev") yield(prev) var next = 1 while (true) { println("Current value is $next") val tmp = next yield(tmp) next = prev + tmp prev = tmp } }
  • 21. Select • select offers the possibility to choose the first result returned by two or more suspending functions, that returns a SelectClause#N. • Biased on the order of the functions. • selectUnbiased solves this issue.
  • 22. Select - example suspend fun randomNumProducer(id: Int) = produce { while (isActive) { send("[${Thread.currentThread().name}] - Produce $id") val sleep = Random().nextInt(50).toLong() delay(sleep) } } suspend fun selectBetween(channel1: ReceiveChannel<String>, channel2: ReceiveChannel<String>) { select<Unit> { channel1.onReceive { println(it) } channel2.onReceiveOrNull { println(it ?: "[${Thread.currentThread().name}] - channel is closed") } } } suspend fun select_example() { val producer1 = randomNumProducer(1) val producer2 = randomNumProducer(2) repeat(5) { selectBetween(producer1, producer2) } producer2.cancel() repeat(3) { selectBetween(producer1, producer2) } }
  • 23. What else? • Non-blocking Mutex. • Channel, like the one used by actor and produce. • Suspending function withTimeout, withTimeoutOrNull and run.
  • 25. What is in there? • kotlinx-coroutines-android, offers the UI context. • kotlinx-coroutines-javafx, offers the JavaFx context. • kotlinx-coroutines-swing, offers the Swing context.
  • 26. UI - example fun ui_example() { launch { val image = async { loadImage() } val title = async { loadTitle() } display(image.await(), title.await()) } } suspend fun display(image: Image, title: String) { run(UI) { // display on UI thread } } suspend fun loadImage(): Image = downloadImage() // non-blocking operation for downloading the image suspend fun loadTitle(): String = downloadTitle() // non-blocking operation for downloading the title
  • 28. What is in there? • kotlinx-coroutines-jdk8, integration with CompletableFuture. • kotlinx-coroutines-nio, integration with JDK7+ Async IO. • kotlinx-coroutines-guava, integration with ListenableFuture. • kotlinx-coroutines-quasar, integration with Quasar library.
  • 29. CompletableFuture • The coroutine builder future. • Extension functions await(). • [!] CompletableFuture should be used only for interacting with existing libraries that use it, otherwise prefer Deferred<T>. • [!!] get() is blocking, await() is not.
  • 30. CompletableFuture - example suspend fun future_example() { val readString = future(context = newSingleThreadContext("read-string")) { stringWithDelay() } val readString2 = future { stringWithDelay() } println("${readString.await()} - ${readString2.await()}") } suspend fun stringWithDelay(): String { println("Current thread is [${Thread.currentThread().name}]") delay(10) println("Current thread is [${Thread.currentThread().name}]") return "future" }
  • 31. kotlinx-coroutines-reactive • Support for RxJava 1.x and 2.x, Reactor and Reactive Streams. • [!] If you’re fine with RxJava than you don’t really need coroutines.
  • 32. Recap • Should you use coroutines in production? YES!! • Should you use coroutines everywhere? NO!! • They still relay on OS threads —> if you call blocking code inside a coroutine, you block the thread on which the coroutine is running —> Be Careful!! • They make sense for IO bound tasks, not CPU bound tasks!!
  • 33. Resources • Channel in Kotlin Slack - #coroutines • KEEP - https://github.com/Kotlin/kotlin-coroutines • Repository - https://github.com/Kotlin/kotlinx.coroutines