Channels examples (#10225)
Co-authored-by: Harihar Das <harihar.das@revolut.com>
This commit is contained in:
parent
a0828bf3d1
commit
f40ed2cef5
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>(1)
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(3) {
|
||||
delay(100)
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>(CONFLATED)
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import com.baeldung.channles.OrderStatus.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
|
||||
enum class OrderStatus { ORDERED, BAKED, TOPPED, SERVED }
|
||||
|
||||
data class PizzaOrder(val orderNumber: Int, val orderStatus: OrderStatus = ORDERED)
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.baking(orders: ReceiveChannel<PizzaOrder>) = produce {
|
||||
for (order in orders) {
|
||||
delay(200)
|
||||
println("Baking ${order.orderNumber}")
|
||||
send(order.copy(orderStatus = BAKED))
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.topping(orders: ReceiveChannel<PizzaOrder>) = produce {
|
||||
for (order in orders) {
|
||||
delay(50)
|
||||
println("Topping ${order.orderNumber}")
|
||||
send(order.copy(orderStatus = TOPPED))
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.produceOrders(count: Int) = produce {
|
||||
repeat(count) {
|
||||
delay(50)
|
||||
send(PizzaOrder(orderNumber = it + 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ObsoleteCoroutinesApi
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val orders = produceOrders(3)
|
||||
|
||||
val readyOrders = topping(baking(orders))
|
||||
|
||||
for (order in readyOrders) {
|
||||
println("Serving ${order.orderNumber}")
|
||||
}
|
||||
|
||||
delay(3000)
|
||||
println("End!")
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.produceFruits(): ReceiveChannel<String> = produce {
|
||||
val fruits = listOf("Apple", "Orange", "Apple")
|
||||
for (fruit in fruits) send(fruit)
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val fruitChannel = produceFruits()
|
||||
for (fruit in fruitChannel) {
|
||||
println(fruit)
|
||||
}
|
||||
println("End!")
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
|
||||
fun main() = runBlocking {
|
||||
val basket = Channel<String>()
|
||||
|
||||
launch { // coroutine1
|
||||
val fruits = listOf("Apple", "Orange", "Banana")
|
||||
for (fruit in fruits) {
|
||||
println("coroutine1: Sending $fruit")
|
||||
basket.send(fruit)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(3) {
|
||||
delay(100)
|
||||
println("coroutine2: Received ${basket.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
suspend fun fetchYoutubeVideos(channel: SendChannel<String>) {
|
||||
val videos = listOf("cat video", "food video")
|
||||
for (video in videos) {
|
||||
delay(100)
|
||||
channel.send(video)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fetchTweets(channel: SendChannel<String>) {
|
||||
val tweets = listOf("tweet: Earth is round", "tweet: Coroutines and channels are cool")
|
||||
for (tweet in tweets) {
|
||||
delay(100)
|
||||
channel.send(tweet)
|
||||
}
|
||||
}
|
||||
|
||||
fun main() = runBlocking {
|
||||
val aggregate = Channel<String>()
|
||||
launch { fetchYoutubeVideos(aggregate) }
|
||||
launch { fetchTweets(aggregate) }
|
||||
|
||||
repeat(4) {
|
||||
println(aggregate.receive())
|
||||
}
|
||||
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.ReceiveChannel
|
||||
import kotlinx.coroutines.channels.produce
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun CoroutineScope.producePizzaOrders(): ReceiveChannel<String> = produce {
|
||||
var x = 1
|
||||
while (true) {
|
||||
send("Pizza Order No. ${x++}")
|
||||
delay(100)
|
||||
}
|
||||
}
|
||||
|
||||
fun CoroutineScope.pizzaOrderProcessor(id: Int, orders: ReceiveChannel<String>) = launch {
|
||||
for (order in orders) {
|
||||
println("Processor #$id is processing $order")
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
fun main() = runBlocking {
|
||||
val pizzaOrders = producePizzaOrders()
|
||||
repeat(3) {
|
||||
pizzaOrderProcessor(it + 1, pizzaOrders)
|
||||
}
|
||||
|
||||
delay(1000)
|
||||
pizzaOrders.cancel()
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.channels.ticker
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.time.Duration
|
||||
import kotlin.random.Random
|
||||
|
||||
fun stockPrice(stock: String): Double {
|
||||
log("Fetching stock price of $stock")
|
||||
return Random.nextDouble(2.0, 3.0)
|
||||
}
|
||||
|
||||
fun main() = runBlocking {
|
||||
val tickerChannel = ticker(Duration.ofSeconds(5).toMillis())
|
||||
|
||||
repeat(3) {
|
||||
tickerChannel.receive()
|
||||
log(stockPrice("TESLA"))
|
||||
}
|
||||
|
||||
delay(Duration.ofSeconds(11).toMillis())
|
||||
tickerChannel.cancel()
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
fun main() = runBlocking {
|
||||
val channel = Channel<Int>(UNLIMITED)
|
||||
|
||||
launch { // coroutine1
|
||||
repeat(100) {
|
||||
println("coroutine1: Sending $it")
|
||||
channel.send(it)
|
||||
}
|
||||
}
|
||||
|
||||
launch { // coroutine2
|
||||
repeat(100) {
|
||||
println("coroutine2: Received ${channel.receive()}")
|
||||
}
|
||||
}
|
||||
|
||||
delay(2000)
|
||||
coroutineContext.cancelChildren()
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.channles
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
fun log(value: Any) {
|
||||
println(SimpleDateFormat("HH:MM:ss").format(Date()) + " - $value")
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.channels
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ChannelsTest {
|
||||
@Test
|
||||
fun should_pass_data_from_one_coroutine_to_another() {
|
||||
runBlocking {
|
||||
// given
|
||||
val channel = Channel<String>()
|
||||
|
||||
// when
|
||||
launch { // coroutine1
|
||||
channel.send("Hello World!")
|
||||
}
|
||||
val result = async { // coroutine 2
|
||||
channel.receive()
|
||||
}
|
||||
|
||||
// then
|
||||
assertThat(result.await()).isEqualTo("Hello World!")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue