You mean it can be done without such cache? Or ju...
# coroutines
n
You mean it can be done without such cache? Or just a common principle for run-like functions?
g
produce created to allow write code inside of lambda, so all your sequence generation code will be encapsulated. But here you already have wrapper
NetworkCallStateProducer
and can just create channel and cache it to property
n
Ok, thanks.
Like this?
Copy code
private val channel = Channel< NetworkCallState<T> >()
    fun getChannel(): ReceiveChannel< NetworkCallState<T> > = channel

    suspend fun produce() {

        do {
            val state: NetworkCallState<T> = suspendCoroutine { cont = it }
            channel.send(state)
        } while (!state.status.isCompleted())
        channel.close()
    }
g
Why do you need suspendCoroutine there?
n
I work with an async API. New state (of network call) is coming via callback. I want to get
Channel<State>
for a call. I know sync calls should be used here. But currently I can use only async calls.
g
Also, looks like you don't need
while
there, you just return channel. Also, you probably want something like BroadcastChannel to support multiple consumers, now you should create a channel for each consumer
But you can just call send on channel inside callback
n
No, I can’t. Callback has no coroutine context. It’s simply
(state) -> Unit
g
Just use
offer
instead of
send
n
Wow! Nice. Thanks👍
Hm.. wait. I lose close() then. Though it may be not so bad –
getChannel().find { it.status.isCompleted() }
.
u
don't use
offer
.it might loose your `state`object if the consume is to slow
Using async network calls is exactly right for coroutines. You just might want to wrap it into suspend function like here: ~https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#wrapping-callbacks~
Then use that suspending function inside you producer
I guess that's pretty much what you already do, just with a little nicer abstraction. keeping the continuation magic isolated
Sorry for my unqualified comment 🙂 I missed that you have a series of state updates
How about calling
channel.send()
inside
run.blocking {}
inside your callback? There you have your coroutine context and depending on the network stack, you might even get back pressure, if the consumer is too slow.