vngantk
02/12/2019, 3:16 AMgildor
02/12/2019, 3:20 AMstreetsofboston
02/12/2019, 3:28 AMDico
02/12/2019, 4:46 AMCoroutineContext
there. Additionally, by implementing the interface with the coroutine object, there is no perdormance loss by treating the two meanings with their own interface.vngantk
02/12/2019, 5:04 AMgildor
02/12/2019, 5:17 AMI have a framework providing function calls doing something that need the support of coroutinesThis is quite abstract, do you have any particular example
explicitly passing the CoroutineContext?This is usually not required for coroutines You must use CoroutineScope if you want start coroutine, this is force you to handle lifecycle See article that I send above, it explains this use case and rationale
vngantk
02/12/2019, 6:04 AMgildor
02/12/2019, 6:22 AMSomewhere down in the framework I need to make asynchronous calls, e.g. launch(), or async().There are official recommendation about this in documentation. Recommended way to use only suspend functions everywhere where it’s possible and use launch/async on top most level in some CoroutineScope. This is why i’m asking about some real use case that you have to suggest how better handle it
vngantk
02/12/2019, 8:13 AMgildor
02/12/2019, 8:19 AMvngantk
02/12/2019, 10:09 AMgildor
02/12/2019, 10:11 AMHow can I wrap this Kotlin callback as coroutineWhat do you mean? You have any example?
I only know that I can wrap a suspending function using launch() or async() which require a CoroutineScope.Exactly, you need coroutine scope. And recommended way to implement CoroutineScope on your class, otherwise you can use GlobalScope, but than you don’t use Structured concurrency and have to handle coroutine lifecycel yourself
vngantk
02/12/2019, 10:16 AMval kotlinCallback: suspend (Message) -> Unit = ...
javaMessageFramework.registerListener(object : JavaMessageListener() {
override fun receive(message: Message) {
GlobalScope.launch {
kotlinCallback.invoke(message)
}
}
}
gildor
02/12/2019, 10:19 AMregisterListener
to suspend function or channel, it will be much more idiomatic API.
Problem of this particular approach, that you do not handle lifecycle of GlobalScope.launch
coroutine, so if kotlinCallback suspend forever or just very long, it will leak itself and all resources of javaMessageFrameworkregisterListener
should be conerted to coroutine itselfvngantk
02/12/2019, 10:21 AMgildor
02/12/2019, 10:22 AMvngantk
02/12/2019, 10:22 AMgildor
02/12/2019, 10:24 AMsuspend fun JavaMessageFramework.awaitMessage() = kotlin.coroutines.suspendCoroutine<Message> { cont ->
registerListener(object : JavaMessageListener() {
override fun receive(message: Message) {
cont.resume(message)
}
}
}
uregisterListener
when coroutine is cancelledskotlinx.coroutines.suspendCancellableCoroutine
builder which provides API to get notification about coroutine cancellationvngantk
02/12/2019, 10:33 AMgildor
02/12/2019, 10:35 AM