Emit/Send Flow Values into BroadcastChannel

771 views Asked by At

been pretty stuck on an issue with Kotlin flows/channels today. Essentially I want to take the values emitted from a flow, and immediately send them in a channel. We then subscribe to that channel as a flow via an exposed method. The use case here is to have a channel subscription that is always live and a flow that can be turned on and off independently.

private val dataChannel = BroadcastChannel<Data>(1)

 suspend fun poll() {
    poller.start(POLLING_PERIOD_MILLISECONDS)
        .collect {
            dataChannel.send(it)
        }
 }

 suspend fun stopPoll() {
     poller.stop()
 }

 suspend fun subscribe(): Flow<Data> {
     return dataChannel.asFlow()
 }

The simple use case I have here is a poller which returns a channelFlow. Ideally I could then emit to the channel in the collect method. This doesn't seem to work though. My rookie coroutine thought is that because collect and send are suspending, the emissions gets suspended in collect and we get stuck.

Is there any built in functions for flow or channel that can handle this or any other way to achieve this behavior?

1

There are 1 answers

0
Sergio On

For your case you can try to use hot stream of data SharedFlow instead of a Channel:

private val dataFlow = MutableSharedFlow<String>(extraBufferCapacity = 1)

 suspend fun poll() {
    poller.start(POLLING_PERIOD_MILLISECONDS)
        .collect {
            dataFlow.tryEmit(it)
        }
 }

 suspend fun stopPoll() {
     poller.stop()
 }

 fun subscribe(): Flow<Data> {
     return dataFlow
 }

tryEmit() - Tries to emit a value to this shared flow without suspending, so calling it will not suspend the collect block.