Zach Klippenstein (he/him) [MOD]
04/25/2019, 5:29 PMproduce
builder doesn’t take a CoroutineStart
parameter? (cc @elizarov)elizarov
04/25/2019, 5:44 PMZach Klippenstein (he/him) [MOD]
04/25/2019, 5:52 PMCoroutineStart
value to `coroutine.start`:
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
}
>> 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.