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

Esa

01/17/2020, 2:55 PM
Hi! Sorry if this is a silly question, but I sort of need to be sure about this. I’m looking to implement Channels for some script we’re using, but the Experimental annotation sort of makes me a bit anxious. How experimental are
CoroutineScope.produce()
,
ReceiveChannel<E>.consumeEach{}
and
ProducerScope.send()
? Is there any way to know? I’ve got a working implementation now, but knowing that it may break without warning is a bit scary. Also, is this the wrong place to ask this question? Is the discussion boards a better place?
e

Evan R.

01/17/2020, 3:23 PM
Since channels are currently stable I’d stick with just using them for now, producers are just syntactic sugar that let you define a coroutine and a channel at the same time. You can easily replace all 3 of those calls with: •
CoroutineScope.produce()
-> define a channel and do a
launch { }
to write values to the channel •
ReceiveChannel<E>.consumeEach{}
->
for (value in channel)
ProducerScope.send()
->
channel.send()
in the
launch { }
block mentioned above
Not to mention you’ll have more flexibility if you launch a coroutine with
launch { }
because then you can produce values to multiple channels at once
Either way,
coroutinescope.produce()
is stable but the API may be subject to change. That’s all the
@ExperimentalCoroutinesApi
annotation means
e

Esa

01/17/2020, 3:44 PM
Allright, thanks. I was using
consumeEach
because it is important that each element is processed only once - the for loop may see some elements be processed by different workers, no?
What I essentially am doing is
repeat(10) { launch { channel.consumeEach { // logic } } }
, so any substitute that ensures each launch gets a unique element is good
t

tseisel

01/18/2020, 8:41 AM
When consuming a channel there is a guarantee that each element be processed only once, even when using multiple workers.
consumeEach
is just an alias of the
for
loop.
e

Esa

01/20/2020, 7:33 AM
Wait, what? Isn’t a for loop just a construct that simply iterates elements from start to finish? Which part of it ensures each element is only processed once in case you
repeat(n)
-workers to iterate it? Not that I doubt you at all, it’s just I don’t see how this is safe when processing only once is important. Enlighten me please 🙂
t

tseisel

01/20/2020, 9:02 AM
I wrote that runnable example : https://pl.kotl.in/7ZarP7sNa It has 1 producer and 5 consumers ; notice how the numbers from 0 to 10 are only printed once each, and processed by different workers.
e

Esa

01/20/2020, 9:19 AM
I can’t get that to run in that webpage, but I’ll try testing it locally. 🙂 Thanks!
e

Evan R.

01/20/2020, 1:43 PM
If you have multiple workers listening to the same channel the contents of the channel should be distributed to each worker in a round-robin fashion, they wouldn’t all receive the same elements. This allows fan-out patterns. If you want to broadcast the same elements of the channel to multiple listeners you might try
BroadcastChannel
In response to your for-loop question, the channel impements
Iterable
by just repeatedly calling
receive()
and so even if you’re using a for loop you’d still receive data the same way
👍 2
3 Views