https://kotlinlang.org logo
#coroutines
Title
# coroutines
y

Yevhenii Nadtochii

06/13/2020, 3:22 AM
Hi all! I'm seeing into Channels\Coroutines in order to implement the next pattern: daemon-coroutine started in the Main thread processes messages from any other coroutines. I see it this way: 1) creating channel 2) launching background coroutine to iterate through channel 3) launching other coroutines that send to channel 4) close channel --> background coroutine terminates But it doesn't work, could anyone say where have I mistaken (code or may be concept itself) ?
Copy code
fun simpleChannelTest() {
    val channel = Channel<String>(capacity = Channel.Factory.UNLIMITED)

    val backgroundProcessor = MainScope().launch {
        for (str in channel) {
            println("$str has been processed")
        }
    }

    runBlocking(Dispatchers.Default) {
        val producers = launch {
            repeat(100) {
                launch {
                    channel.send("str$it")
                }
            }
        }

        println("producers have been created")
        producers.join()
        println("producers have done their work")
        channel.close()
        println("channel has been closed")
        backgroundProcessor.join() // ********************* I"M STUCK HERE
        println("backgroundProcessor coroutine has done its job") // ***************** UNREACHABLE
    }
v

vaskir

06/13/2020, 7:36 AM
Copy code
fun main() = runBlocking {
    val channel = Channel<String>(capacity = Channel.UNLIMITED)

    val backgroundProcessor = launch {
        for (str in channel) {
            println("$str has been processed")
        }
    }

    runBlocking(Dispatchers.Default) {
        val producers = launch {
            repeat(10) {
                channel.send("str$it")
            }
        }
        println("producers have been created")
        producers.join()
        println("producers have done their work")
        channel.close()
        println("channel has been closed")
        backgroundProcessor.join()
        println("backgroundProcessor coroutine has done its job")
    }
}
output:
Copy code
producers have been created
str0 has been processed
producers have done their work
str1 has been processed
str2 has been processed
str3 has been processed
str4 has been processed
str5 has been processed
str6 has been processed
str7 has been processed
str8 has been processed
str9 has been processed
channel has been closed
backgroundProcessor coroutine has done its job
I'm not sure what's
MainScope
is for in your code though, but it seems the problem is in it.
💯 1
y

Yevhenii Nadtochii

06/13/2020, 11:13 AM
It didn't come to me to check if this coroutine starts at all. It was marked as
Active
, but actually - it's been suspended from the very beginning as current test executor and
Dispatchers.Main
were using the same thread ==> dead lock occurred at this point
backgroundProcessor.join()
Thank you, since now will be using
-Dkotlinx.coroutines.debug
before writing here :)
🎉 1
4 Views