Slide 1

Slide 1 text

Jag Saund Concurrency doesn’t have to be hard:
 Kotlin Coroutines & Channels

Slide 2

Slide 2 text

Loaders Threads AsyncTask Callbacks Futures RxJava Functional Functional Reactive

Slide 3

Slide 3 text

Loaders Threads AsyncTask Callbacks Futures RxJava Functional Functional Reactive Coroutines and Channels Communicating Sequential Processes (CSP)

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

https://jagstalk.page.link/examples

Slide 6

Slide 6 text

https://jagstalk.page.link/examples

Slide 7

Slide 7 text

https://jagstalk.page.link/examples

Slide 8

Slide 8 text

fun main() { val orders = listOf( Menu.Cappuccino(CoffeeBean.Regular, Milk.Whole), Menu.Cappuccino(CoffeeBean.Premium, Milk.Breve), Menu.Cappuccino(CoffeeBean.Regular, Milk.NonFat), Menu.Cappuccino(CoffeeBean.Decaf, Milk.Whole), Menu.Cappuccino(CoffeeBean.Regular, Milk.NonFat), Menu.Cappuccino(CoffeeBean.Decaf, Milk.NonFat) ) } https://jagstalk.page.link/examples

Slide 9

Slide 9 text

fun main() { val orders = listOf(...) } https://jagstalk.page.link/examples

Slide 10

Slide 10 text

fun main() { val orders = listOf(...) orders.forEach { } } https://jagstalk.page.link/examples

Slide 11

Slide 11 text

fun main() { val orders = listOf(...) orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) } } https://jagstalk.page.link/examples

Slide 12

Slide 12 text

fun main() { val orders = listOf(...) orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) } } https://jagstalk.page.link/examples

Slide 13

Slide 13 text

fun main() { val orders = listOf(...) orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) } } https://jagstalk.page.link/examples

Slide 14

Slide 14 text

fun main() { val orders = listOf(...) orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) } } https://jagstalk.page.link/examples

Slide 15

Slide 15 text

fun main() { val orders = listOf(...) orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 16

Slide 16 text

fun main() { val orders = listOf(...) val time = measureTimeMillis { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } log("time: $time ms") } https://jagstalk.page.link/examples

Slide 17

Slide 17 text

fun main() { val orders = listOf(...) val time = measureTimeMillis { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } log("time: $time ms") } https://jagstalk.page.link/examples

Slide 18

Slide 18 text

fun main() {...} private fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { log("grinding coffee beans") sleep(1000) return CoffeeBean.GroundBeans(beans) } private fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { log("pulling espresso shot") sleep(600) return Espresso(groundBeans) } private fun steamMilk(milk: Milk): Milk.SteamedMilk { log("steaming milk") sleep(300) return Milk.SteamedMilk(milk) } private fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { log("making cappuccino") sleep(100) return Beverage.Cappuccino(order, espresso, steamedMilk) } https://jagstalk.page.link/examples

Slide 19

Slide 19 text

fun main() { val orders = listOf(...) val time = measureTimeMillis { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } log("time: $time ms") } private fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } https://jagstalk.page.link/examples

Slide 20

Slide 20 text

https://jagstalk.page.link/examples

Slide 21

Slide 21 text

https://jagstalk.page.link/examples

Slide 22

Slide 22 text

fun main() { val orders = listOf(...) val time = measureTimeMillis { } log("time: $time ms") } private fun processOrders(orders: List) { } orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } https://jagstalk.page.link/examples

Slide 23

Slide 23 text

private fun processOrders(orders: List) { } fun main() { val orders = listOf(...) val time = measureTimeMillis { processOrders(orders) } log("time: $time ms") } https://jagstalk.page.link/examples orders.forEach { val groundBeans = grindCoffeeBeans(it.beans) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") }

Slide 24

Slide 24 text

fun main() { val orders = listOf(...) val time = measureTimeMillis { launch { processOrders(orders) } launch { processOrders(orders) } } log("time: $time ms”) } private fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 25

Slide 25 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { launch { processOrders(orders) } launch { processOrders(orders) } } log("time: $time ms”) } private fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 26

Slide 26 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } log("time: $time ms”) } private fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 27

Slide 27 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } log("time: $time ms”) } private fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 28

Slide 28 text

private fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { log("grinding coffee beans") sleep(1000) return CoffeeBean.GroundBeans(beans) } private fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { log("pulling espresso shot") sleep(600) return Espresso(groundBeans) } private fun steamMilk(milk: Milk): Milk.SteamedMilk { log("steaming milk") sleep(300) return Milk.SteamedMilk(milk) } private fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { log("making cappuccino") sleep(100) return Beverage.Cappuccino(order, espresso, steamedMilk) } fun main() {...} https://jagstalk.page.link/examples

Slide 29

Slide 29 text

private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { log("grinding coffee beans") delay(1000) return CoffeeBean.GroundBeans(beans) } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { log("pulling espresso shot") delay(600) return Espresso(groundBeans) } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { log("steaming milk") delay(300) return Milk.SteamedMilk(milk) } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { log("making cappuccino") delay(100) return Beverage.Cappuccino(order, espresso, steamedMilk) } fun main() {...} https://jagstalk.page.link/examples

Slide 30

Slide 30 text

fun main() {...} private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { log("grinding coffee beans") delay(1000) return CoffeeBean.GroundBeans(beans) } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { log("pulling espresso shot") delay(600) return Espresso(groundBeans) } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { log("steaming milk") delay(300) return Milk.SteamedMilk(milk) } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { log("making cappuccino") delay(100) return Beverage.Cappuccino(order, espresso, steamedMilk) } https://jagstalk.page.link/examples

Slide 31

Slide 31 text

private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } fun main() {...} https://jagstalk.page.link/examples

Slide 32

Slide 32 text

private fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } fun main() {...} https://jagstalk.page.link/examples

Slide 33

Slide 33 text

private suspend fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } fun main() {...} https://jagstalk.page.link/examples

Slide 34

Slide 34 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } log("time: $time ms”) } private suspend fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } https://jagstalk.page.link/examples

Slide 35

Slide 35 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } } log("time: $time ms”) } private suspend fun processOrders(orders: List) { orders.forEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } private suspend fun grindCoffeeBeans(beans: CoffeeBean): CoffeeBean.GroundBeans { ... } private suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { ... } private suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { ... } private suspend fun makeCappuccino(order: Menu.Cappuccino, espresso: Espresso, steamedMilk: Milk.SteamedMilk): Beverage.Cappuccino { ... } https://jagstalk.page.link/examples

Slide 36

Slide 36 text

https://jagstalk.page.link/examples Sender Coroutine Receiver Coroutine Channel

Slide 37

Slide 37 text

https://jagstalk.page.link/examples Sender Coroutine Receiver Coroutine Channel Data

Slide 38

Slide 38 text

https://jagstalk.page.link/examples Sender Coroutine (suspended) Receiver Coroutine Channel Data Z Z Z

Slide 39

Slide 39 text

https://jagstalk.page.link/examples Sender Coroutine (suspended) Receiver Coroutine (busy) Channel Data Z Z Z

Slide 40

Slide 40 text

https://jagstalk.page.link/examples Sender Coroutine Receiver Coroutine Channel

Slide 41

Slide 41 text

https://jagstalk.page.link/examples Sender Coroutine Receiver Coroutine Channel

Slide 42

Slide 42 text

https://jagstalk.page.link/examples Receiver Coroutine Channel Sender Coroutine (suspended) Z Z Z

Slide 43

Slide 43 text

https://jagstalk.page.link/examples Receiver Coroutine (suspended) Channel Sender Coroutine Z Z Z

Slide 44

Slide 44 text

https://jagstalk.page.link/examples Conflated Channel Sender Coroutine Receiver Coroutine (busy)

Slide 45

Slide 45 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } } log("time: $time ms”) } val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } https://jagstalk.page.link/examples

Slide 46

Slide 46 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(orders) } launch(CoroutineName("barista-2")) { processOrders(orders) } } } log("time: $time ms”) } val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } https://jagstalk.page.link/examples

Slide 47

Slide 47 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } https://jagstalk.page.link/examples

Slide 48

Slide 48 text

private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } https://jagstalk.page.link/examples

Slide 49

Slide 49 text

val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 50

Slide 50 text

main coroutine val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 51

Slide 51 text

main coroutine channel main coroutine val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 52

Slide 52 text

main coroutine channel val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 53

Slide 53 text

main coroutine channel val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 54

Slide 54 text

main coroutine (suspended) channel val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 55

Slide 55 text

val ordersChannel = Channel() orders.forEach { ordersChannel.send(it) } fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms”) } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 56

Slide 56 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms") } val ordersChannel = Channel() launch(CoroutineName("cashier")) { orders.forEach { ordersChannel.send(it) } } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 57

Slide 57 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms") } val ordersChannel = produce(CoroutineName("cashier")) { orders.forEach { send(it) } } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 58

Slide 58 text

fun main() = runBlocking { val orders = listOf(...) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel) } } } log("time: $time ms") } val ordersChannel = produce(CoroutineName("cashier")) { orders.forEach { send(it) } } private suspend fun processOrders(ordersChannel: Channel) { ordersChannel.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = pullEspressoShot(groundBeans) val steamedMilk = steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples produce coroutine

Slide 59

Slide 59 text

Cashier Barista 1 Barista 2 suspended suspended https://jagstalk.page.link/examples

Slide 60

Slide 60 text

Cashier Barista 1 Barista 2 suspended suspended https://jagstalk.page.link/examples

Slide 61

Slide 61 text

Cashier Barista 1 Barista 2 active suspended https://jagstalk.page.link/examples

Slide 62

Slide 62 text

Cashier Barista 1 Barista 2 active suspended https://jagstalk.page.link/examples

Slide 63

Slide 63 text

Cashier Barista 1 Barista 2 active suspended https://jagstalk.page.link/examples

Slide 64

Slide 64 text

Cashier Barista 1 Barista 2 active active https://jagstalk.page.link/examples

Slide 65

Slide 65 text

Cashier Barista 1 Barista 2 active active https://jagstalk.page.link/examples

Slide 66

Slide 66 text

Cashier Barista 1 Barista 2 active active suspended https://jagstalk.page.link/examples

Slide 67

Slide 67 text

Cashier Barista 1 Barista 2 suspended active active https://jagstalk.page.link/examples

Slide 68

Slide 68 text

Cashier Barista 1 Barista 2 suspended active active https://jagstalk.page.link/examples

Slide 69

Slide 69 text

Cashier Barista 1 Barista 2 active active active https://jagstalk.page.link/examples

Slide 70

Slide 70 text

Cashier Barista 1 Barista 2 active active suspended https://jagstalk.page.link/examples

Slide 71

Slide 71 text

Cashier Barista 1 Barista 2 active active Close Channel https://jagstalk.page.link/examples

Slide 72

Slide 72 text

Cashier Barista 1 Barista 2 https://jagstalk.page.link/examples

Slide 73

Slide 73 text

https://jagstalk.page.link/examples

Slide 74

Slide 74 text

class EspressoMachine { suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } } https://jagstalk.page.link/examples

Slide 75

Slide 75 text

class EspressoMachine { suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } private suspend fun processEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { log("pulling espresso shot") delay(600) return Espresso(groundBeans) } private suspend fun processSteamMilk(milk: Milk): Milk.SteamedMilk { log("steaming milk") delay(300) return Milk.SteamedMilk(milk) } } https://jagstalk.page.link/examples

Slide 76

Slide 76 text

class EspressoMachine { suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } } private suspend fun processEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso {...} private suspend fun processSteamMilk(milk: Milk): Milk.SteamedMilk {…} https://jagstalk.page.link/examples

Slide 77

Slide 77 text

Portafilter 1 Portafilter 2 Barista https://jagstalk.page.link/examples

Slide 78

Slide 78 text

Portafilter 1 Portafilter 2 Barista https://jagstalk.page.link/examples ?

Slide 79

Slide 79 text

Portafilter 1 Portafilter 2 Barista https://jagstalk.page.link/examples Coroutine Coroutine ?

Slide 80

Slide 80 text

Portafilter 1 Portafilter 2 Barista https://jagstalk.page.link/examples Coroutine Coroutine Channel Channel ?

Slide 81

Slide 81 text

https://jagstalk.page.link/examples actor coroutine channel

Slide 82

Slide 82 text

class EspressoMachine { private val portafilterOne: SendChannel = actor { consumeEach { groundBeans -> val espresso = processEspressoShot(groundBeans) TODO("deliver espresso shot to sender") } } suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } } private suspend fun processEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso {...} private suspend fun processSteamMilk(milk: Milk): Milk.SteamedMilk {…} https://jagstalk.page.link/examples

Slide 83

Slide 83 text

class EspressoMachine { private val portafilterOne: SendChannel = actor { consumeEach { groundBeans -> val espresso = processEspressoShot(groundBeans) TODO("deliver espresso shot to sender") } }
 private val portafilterTwo: SendChannel = actor { consumeEach { groundBeans -> val espresso = processEspressoShot(groundBeans) TODO("deliver espresso shot to sender") } } suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } private suspend fun processEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso {...} private suspend fun processSteamMilk(milk: Milk): Milk.SteamedMilk {...} } https://jagstalk.page.link/examples

Slide 84

Slide 84 text

Portafilter 1 Portafilter 2 Barista https://jagstalk.page.link/examples ?

Slide 85

Slide 85 text

Portafilter 1 Portafilter 2 Barista select https://jagstalk.page.link/examples

Slide 86

Slide 86 text

Barista Portafilter 1 Portafilter 2 select Select Like a switch statement Works on Send and Receive Shape Data Flow https://jagstalk.page.link/examples

Slide 87

Slide 87 text

class EspressoMachine { private val portafilterOne: SendChannel = actor { consumeEach { groundBeans -> val espresso = processEspressoShot(groundBeans) TODO("deliver espresso shot to sender") } }
 private val portafilterTwo: SendChannel = actor { consumeEach { groundBeans -> val espresso = processEspressoShot(groundBeans) TODO("deliver espresso shot to sender") } } suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { TODO("pull espresso shot not implemented") } suspend fun steamMilk(milk: Milk): Milk.SteamedMilk { TODO("steam milk not implemented") } private suspend fun processEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso {...} private suspend fun processSteamMilk(milk: Milk): Milk.SteamedMilk {...} } https://jagstalk.page.link/examples

Slide 88

Slide 88 text

class EspressoMachine { private val portafilterOne: SendChannel = actor {...}
 private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { return select { portafilterOne.onSend(groundBeans) { TODO("sent to portafilter one - wait for result") } portafilterTwo.onSend(groundBeans) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 89

Slide 89 text

Portafilter 1 Portafilter 2 Barista select https://jagstalk.page.link/examples

Slide 90

Slide 90 text

class EspressoMachine { private val portafilterOne: SendChannel = actor {...}
 private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { return select { portafilterOne.onSend(groundBeans) { TODO("sent to portafilter one - wait for result") } portafilterTwo.onSend(groundBeans) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 91

Slide 91 text

class EspressoMachine { private data class EspressoShotRequest( val deferredEspressoShot: CompletableDeferred, val groundBeans: CoffeeBean.GroundBeans ) private val portafilterOne: SendChannel = actor {...}
 private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { return select { portafilterOne.onSend(groundBeans) { TODO("sent to portafilter one - wait for result") } portafilterTwo.onSend(groundBeans) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 92

Slide 92 text

class EspressoMachine { private data class EspressoShotRequest( val deferredEspressoShot: CompletableDeferred, val groundBeans: CoffeeBean.GroundBeans ) private val portafilterOne: SendChannel = actor { consumeEach { request -> val espresso = processEspressoShot(request.groundBeans) request.deferredEspressoShot.complete(espresso) } } private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { return select { portafilterOne.onSend(groundBeans) { TODO("sent to portafilter one - wait for result") } portafilterTwo.onSend(request) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 93

Slide 93 text

class EspressoMachine { private data class EspressoShotRequest( val deferredEspressoShot: CompletableDeferred, val groundBeans: CoffeeBean.GroundBeans ) private val portafilterOne: SendChannel = actor { consumeEach { request -> val espresso = processEspressoShot(request.groundBeans) request.deferredEspressoShot.complete(espresso) } } private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { val request = EspressoShotRequest(CompletableDeferred(), groundBeans) return select { portafilterOne.onSend(request) { request.deferredEspressoShot.await() } portafilterTwo.onSend(request) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 94

Slide 94 text

class EspressoMachine(scope: CoroutineScope): CoroutineScope by scope { private data class EspressoShotRequest( val deferredEspressoShot: CompletableDeferred, val groundBeans: CoffeeBean.GroundBeans ) private val portafilterOne: SendChannel = actor { consumeEach { request -> val espresso = processEspressoShot(request.groundBeans) request.deferredEspressoShot.complete(espresso) } } private val portafilterTwo: SendChannel = actor {...} suspend fun pullEspressoShot(groundBeans: CoffeeBean.GroundBeans): Espresso { val request = EspressoShotRequest(CompletableDeferred(), groundBeans) return select { portafilterOne.onSend(request) { request.deferredEspressoShot.await() } portafilterTwo.onSend(request) { TODO("sent to portafilter two - wait for result") } } } ... } https://jagstalk.page.link/examples

Slide 95

Slide 95 text

class EspressoMachine(scope: CoroutineScope): CoroutineScope by scope { ... } fun main() = runBlocking { ... val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") } private suspend fun processOrders(orders: ReceiveChannel, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espresso = espressoMachine.pullEspressoShot(groundBeans) val steamedMilk = espressoMachine.steamMilk(it.milk()) val cappuccino = makeCappuccino(it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 96

Slide 96 text

private suspend fun processOrders(orders: ReceiveChannel, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino( it, espresso, steamedMilk) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 97

Slide 97 text

private suspend fun processOrders(orders: ReceiveChannel, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino( it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 98

Slide 98 text

private suspend fun processOrders(orders: ReceiveChannel, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino( it, espressoDeferred.await(), steamedMilkDeferred.await()) } log("serve: $cappuccino") } } https://jagstalk.page.link/examples

Slide 99

Slide 99 text

Flow Channels are for Hot Streams Flow is for Cold Streams Flow is activated with collect https://jagstalk.page.link/examples

Slide 100

Slide 100 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersChannel = produce(CoroutineName("cashier")) { orders.forEach { send(it) } } val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") espressoMachine.destroy() }

Slide 101

Slide 101 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersChannel = produce(CoroutineName("cashier")) { orders.forEach { send(it) } } val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") espressoMachine.destroy() }

Slide 102

Slide 102 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") espressoMachine.destroy() }

Slide 103

Slide 103 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") espressoMachine.destroy() }

Slide 104

Slide 104 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: ReceiveChannel, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 105

Slide 105 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 106

Slide 106 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine) { orders.consumeEach { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 107

Slide 107 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine) { orders.map { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 108

Slide 108 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine) { orders.map { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } val cappuccino = makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) log("serve: $cappuccino") } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 109

Slide 109 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine) { orders.map { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) } } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 110

Slide 110 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine): Flow = orders.map { val groundBeans = grindCoffeeBeans(it.beans()) coroutineScope { val espressoDeferred = async { espressoMachine.pullEspressoShot(groundBeans) } val steamedMilkDeferred = async { espressoMachine.steamMilk(it.milk()) } makeCappuccino(it, espressoDeferred.await(), steamedMilkDeferred.await()) } } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { ... } log("time: $time ms") espressoMachine.destroy() }

Slide 111

Slide 111 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine): Flow { ...
 } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { coroutineScope { launch(CoroutineName("barista-1")) { processOrders(ordersChannel, espressoMachine) } launch(CoroutineName("barista-2")) { processOrders(ordersChannel, espressoMachine) } } } log("time: $time ms") espressoMachine.destroy() }

Slide 112

Slide 112 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine): Flow { ...
 } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { flowOf( processOrders(ordersFlow, espressoMachine), processOrders(ordersFlow, espressoMachine) ) } log("time: $time ms") espressoMachine.destroy() }

Slide 113

Slide 113 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine): Flow { ...
 } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { flowOf( processOrders(ordersFlow, espressoMachine), processOrders(ordersFlow, espressoMachine) ) .flattenMerge() } log("time: $time ms") espressoMachine.destroy() }

Slide 114

Slide 114 text

https://jagstalk.page.link/examples private suspend fun processOrders(orders: Flow, espressoMachine: EspressoMachine): Flow { ...
 } fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { flowOf( processOrders(ordersFlow, espressoMachine), processOrders(ordersFlow, espressoMachine) ) .flattenMerge() .collect { cappuccino -> log("serve: $cappuccino") } } log("time: $time ms") espressoMachine.destroy() }

Slide 115

Slide 115 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() .produceIn(this) .asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { flowOf( processOrders(ordersFlow, espressoMachine), processOrders(ordersFlow, espressoMachine) ) .flattenMerge() .collect { cappuccino -> log("serve: $cappuccino") } } log("time: $time ms") espressoMachine.destroy() }

Slide 116

Slide 116 text

https://jagstalk.page.link/examples fun main() = runBlocking { val orders = listOf(...) val ordersFlow: Flow = orders.asFlow() .produceIn(this) .asFlow() val espressoMachine = EspressoMachine(this) val time = measureTimeMillis { flowOf( processOrders(ordersFlow, espressoMachine), processOrders(ordersFlow, espressoMachine) ) .flattenMerge() .collect { cappuccino -> log("serve: $cappuccino") } } log("time: $time ms") espressoMachine.destroy() } private fun ReceiveChannel.asFlow(): Flow = flow { consumeEach { value -> emit(value) } }

Slide 117

Slide 117 text

https://jagstalk.page.link/examples

Slide 118

Slide 118 text

https://jagstalk.page.link/examples

Slide 119

Slide 119 text

Q&A Concurrency doesn’t have to be hard: Kotlin Coroutines & Channels