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

nil2l

12/11/2017, 10:53 AM
You mean it can be done without such cache? Or just a common principle for run-like functions?
g

gildor

12/11/2017, 10:55 AM
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

nil2l

12/11/2017, 10:56 AM
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

gildor

12/11/2017, 11:20 AM
Why do you need suspendCoroutine there?
n

nil2l

12/11/2017, 11:23 AM
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

gildor

12/11/2017, 11:27 AM
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

nil2l

12/11/2017, 11:31 AM
No, I can’t. Callback has no coroutine context. It’s simply
(state) -> Unit
g

gildor

12/11/2017, 11:41 AM
Just use
offer
instead of
send
n

nil2l

12/11/2017, 11:42 AM
Wow! Nice. Thanks👍
Hm.. wait. I lose close() then. Though it may be not so bad –
getChannel().find { it.status.isCompleted() }
.
u

uli

12/11/2017, 8:32 PM
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.
5 Views