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

Zach Klippenstein (he/him) [MOD]

04/25/2019, 5:29 PM
Does anyone know why the
produce
builder doesn’t take a
CoroutineStart
parameter? (cc @elizarov)
e

elizarov

04/25/2019, 5:44 PM
TooManyParametersException. What's your use-case for it?
z

Zach Klippenstein (he/him) [MOD]

04/25/2019, 5:52 PM
That’s surprising, it only has at most 5 parameters currently, and is already passing some
CoroutineStart
value to `coroutine.start`:
Copy code
public fun <E> CoroutineScope.produce(
    context: CoroutineContext = EmptyCoroutineContext,
    capacity: Int = 0,
    onCompletion: CompletionHandler? = null,
    @BuilderInference block: suspend ProducerScope<E>.() -> Unit
): ReceiveChannel<E> {
    val channel = Channel<E>(capacity)
    val newContext = newCoroutineContext(context)
    val coroutine = ProducerCoroutine(newContext, channel)
    if (onCompletion != null) coroutine.invokeOnCompletion(handler = onCompletion)
    coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
    return coroutine
}
Found this issue, wrote up my use case there: https://github.com/Kotlin/kotlinx.coroutines/issues/845
>> I have a different use case for this. I have a coroutine that runs a loop to process a UI framework (calculate an initial state, wait for events, calculate new state, repeat). It starts this coroutine using the produce builder to publish updates on a channel. The coroutine is guaranteed to calculate its first state without suspending. In order to integrate with legacy, non-coroutine code, I need to get that first state from a non-suspend function.
As far as I know, there are two ways to do this: Call poll() on the channel. Assumes the initial value has already been sent. Call runBlocking { channel.receive() }. I would prefer 1, because it doesn’t actually block at all, and doesn’t require the overhead of allocating a whole new dispatch queue and coroutine just to receive a value that should be immediately available anyway. However, the legacy code that needs to get this value is running on the same thread and hasn’t given the produce coroutine a chance to execute its initial continuation yet. I believe if I could start the produce coroutine with CoroutineStart.UNDISPATCHED, that initial value would get calculated and sent on the channel immediately, and I could use poll.
4 Views