I'll be giving a small introduction into coroutine...
# coroutines
m
I'll be giving a small introduction into coroutines at the work, any modifications or additions on this?
👍 2
o
I am as well presenting it. Maybe something can be taken useful from here(but it just initial iteration):
Copy code
Coroutine in Kotlin
 
 * allows suspension in the middle of execution
 
 * small resources are occupied during suspension(threads are free)
 
 * suspension achieved by code transformation at compile time
 
 * shortly, it solves the problem of callback hell in asynchronous programs
👍 1
🚀 1
Copy code
Kotlin

 * as a language, provides only minimal low-level APIs
 
 * e.g. `async` and `await` are not keywords in Kotlin, not even in the standard library
 
 * concept of suspending function provides a safer abstraction for asynchronous operations than futures and promises.
 
 * on another hand `kotlinx.coroutines` is a rich library with many primitives
   
Simplest example
  
import kotlinx.coroutines.*

fun main() {
    GlobalScope.launch {  // launch new coroutine
    
        delay(1000L)      // do not block any thread
                          // and schedules continunation to be executed
                          // after 1 second
                          
        println("World!") // continuation
    }
    
    println("Hello,")
    Thread.sleep(2000L)   // block main thread for 2 seconds
}


here GlobalScope allows launching coroutines as a daemon

Blocking world bridge

import kotlinx.coroutines.*

fun main() = runBlocking {
    repeat(100_000) { // launch a lot of coroutines, not a problem
        launch {
            delay(1000L)
            print(".")
        }
    }
}

here launch is performed in the scope of runBlocking, not global scope
runBlocking waits for all launched coroutines to finish
runBlocking blocks the thread that was executed on

Cancellation

val job = launch {
    try {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    } finally {
        println("I'm running finally")
    }
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")

I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
main: I'm tired of waiting!
I'm running finally
main: Now I can quit.

import kotlinx.coroutines.*
import kotlin.system.*

Async / await

fun main() = runBlocking {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    println("The answer is ${one.await() + two.await()}")
}

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}
Copy code
Adapting any asynchronous library to coroutines

fun sync() {
    val client = OkHttpClient();

    val request = Request.Builder()
        .url("<https://www.ubs.com>")
        .build();

    val call: Call = client.newCall(request)

    val execute: Response = call.execute()

    println(execute.message())
}

Adapting any asynchronous library to coroutines

fun async() {
    val client = OkHttpClient();

    val request = Request.Builder()
        .url("<https://www.ubs.com>")
        .build();

    val call: Call = client.newCall(request)

    call.enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            println("Error: " + e.message)
        }

        override fun onResponse(call: Call, response: Response) {
            println(response.message())
        }
    });
}

Adapting any asynchronous library to coroutines

suspend fun suspended() {
    val client = OkHttpClient();

    val request = Request.Builder()
        .url("<https://www.ubs.com>")
        .build();

    val call: Call = client.newCall(request)

    val response: Response = enqueueAndWait(call)

    println(response.message())
}

suspend fun enqueueAndWait(call: Call): Response = suspendCoroutine { continuation ->
    call.enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            continuation.resumeWithException(e)
        }

        override fun onResponse(call: Call, response: Response) {
            continuation.resume(response)
        }
    })
}

Adaptor libraries in kotlinx.coroutine

kotlinx-coroutines-reactive      -- utilities for Reactive Streams
kotlinx-coroutines-reactor       -- utilities for Reactor
kotlinx-coroutines-rx2           -- utilities for RxJava 2.x
kotlinx-coroutines-jdk8          -- integration with JDK8 CompletableFuture (Android API level 24).
kotlinx-coroutines-guava         -- integration with Guava ListenableFuture.
kotlinx-coroutines-slf4j         -- integration with SLF4J MDC.
kotlinx-coroutines-play-services -- integration with Google Play Services Tasks API.
kotlinx-coroutines-android       -- Dispatchers.Main context for Android applications.
kotlinx-coroutines-javafx        -- Dispatchers.JavaFx context for JavaFX UI applications.
kotlinx-coroutines-swing         -- Dispatchers.Swing context for Swing UI applications.

Any asynchronous library may be adapted like we've seen with OkHttp quite easily

Example of reactor mono / flux

val mono: Mono<Int> = mono {
    delay(500)
    5
}

val flux: Flux<Int> = flux {
    for (i in 1..10) {
        send(i)
        delay(500)
    }
}
m
thanks for all of above 🙂