What’s more idiomatic: ``` fun events(channel: Sen...
# coroutines
a
What’s more idiomatic:
Copy code
fun events(channel: SendChannel<Event>)
fun events(scope: CoroutineScope): ReceiveChannel<Event>
In my case I need to add a listener when calling
events
and remove it when the channel is closed
a
I don’t have multiple consumers and I need the caller to be the one to close the channel
a
Oh, I’ll try that.
d
But to answer your actual question, I think the second one is more idiomatic. 🙂
a
Hmm, I don’t really think BroadcastChannel would fit my use case because I need a clear open and close event
d
Makes sense.
Even
fun CoroutineScope.events(): ReceiveChannel<Event>
is more idiomatic if you're a spawning a coroutine in the function.
a
It’s really strange though, my producer is closed instantly and I can’t figure out why:
Copy code
override fun events(scope: CoroutineScope): ReceiveChannel<Unit> =
        scope.produce(capacity = Channel.CONFLATED) {
            val listener = { offer(Unit) }
            addListener(listener)
            invokeOnClose { removeListener(listener) }
        }
d
Oh, I don't think you need the
produce
.
Just create a channel and return it.
a
The reason why I need it is because it will be closed when the scope’s job is cancelled
If I have a channel I need to close it manually
d
Hmm, there's a way to register a callback with the scope's context to handle closing but I don't know how atm.
You definitely don't need a coroutine for this.
a
Well I don’t want the caller to have to worry about closing the channel
d
This is a common problem indeed, where the channel is closed when the
produce
coroutine completes, when that is not the intention. Here is a potential workaround:
Copy code
produce {
    // your stuff, done with procuding ...
    suspendCoroutineCancellable<Unit> { cont ->
        channel.invokeOnClose { cont.resume(Unit) }
    }   
}
a
Oh right, of course. The coroutine completes. What would be the best way to have this behavior then?
d
well, there are 2 options for you, the one above or to manually close the channel when the scope is cancelled.
I'm actually confused now, as channels should only be closed for sending when the producer completes. Any sent items should still be receivable.
Ah, it's because of the listener thing you're doing.
a
Yeah, I’m trying to bridge a callback API
d
I see