Zach Klippenstein (he/him) [MOD]
09/15/2018, 5:28 PMJob
from a runBlocking
scope. Changing the dispatcher doesn’t seem to matter, and coroutines `launch`ed from GlobalScope
execute the handler as I’d expect. I can’t see any documentation about this or figure out how this makes sense.
E.g.
fun main(args: Array<String>) {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
runBlocking(handler) {
val job = launch {
// This exception is thrown from runBlocking, and not seen by handler.
throw AssertionError()
}
job.join()
}
}
If you change that to the following, handler
gets run:
runBlocking {
val job = GlobalScope.launch(handler) {
Is this behavior by design?Kotlin
09/15/2018, 8:02 PMacando86
09/16/2018, 9:29 AMzjuhasz
09/16/2018, 11:55 AMCoroutineScope
, unless the coroutines created by that class should always act globally for the full lifetime of the application. This means every class that launches coroutines should be created through an extension function on CoroutineScope
like CoroutineScope.MyClass()
. So MyClass
needs a constructor that takes scope as a parameter, then we need to make an extension function for CoroutineScope
that is an exact copy of the constructor for MyClass
except it uses this
from CoroutineScope
instead of taking scope as a parameter. If there is a class with several constructors that each have several parameters this can be really annoying and a bit hard to maintain. Is there a better way for me to be scoping the coroutines launched by classes?ashdavies
09/17/2018, 7:53 AMPavel.AZ
09/17/2018, 12:45 PMMartin Devillers
09/17/2018, 1:01 PMabstract class ScopedAppActivity: AppCompatActivity(), CoroutineScope {
protected lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
job = Job()
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
}
https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy
It seems to me that this example is needlessly complicated. The following would work just as well.
abstract class ScopedAppActivity: AppCompatActivity(), CoroutineScope {
override val coroutineContext: CoroutineContext = Job()
override fun onDestroy() {
super.onDestroy()
coroutineContext[Job]?.cancel()
}
}
Since Dispatchers.Main
is the ContinuationInterceptor
used when none is available in a CoroutineContext
, this should yield the same result. Is there something I’m missing?ashdavies
09/17/2018, 1:22 PMCoroutineScope
with LifecycleObserver
so you can avoid having to use inheritanceAlbert
09/17/2018, 1:44 PM@Test fun testActor() {
val testActor = actor<String> {
println(channel.receive())
}
testActor.sendBlocking("CHANNEL-MESSAGE")
}
When I run this locally on my machine I see CHANNEL-MESSAGE
being printed. But when I build this with docker it is never received. My Dockerfile
looks like:
FROM maven:3.3.9-jdk-8
COPY . project/
WORKDIR project
RUN mvn clean package
I used version 3.3.9
which is the same on my local machine. With docker it actually freezes on the sendBlocking
.
Anyone a clue how this is possible?Jonathan
09/17/2018, 2:34 PMunsafeMethod
fails it will make the parent job fail, which basically mean a crash of the UI componenent (any working coroutine will be cancelled and further action would no longer work)
Of course I could encapsulate the call in try-catch
. But it is a bit boilerplate and easy to forget. (here it is obvious, but what about unexpected exceptions?)
How could I launch a child coroutine in a way that it does'nt propagate the failure to the parent?nwh
09/17/2018, 9:02 PMcall to 'resume' before 'invoke' with coroutine
error, but I'm having a hard time figuring out what's causing it and I can't seem to isolate it (though I can reproduce in this single environment). Any suggestions on how to track it down?Allan Wang
09/17/2018, 10:00 PMlaunch
blocks?
I have a method created like so:
suspend fun <T> Deferred<T>.awaitOrRedirect(context: Context): T? =
try {
await()
} catch (e: Exception) {
logd("Error, redirect to Login")
LoginActivity.launch(context)
null
}
But the errors seem to just pass through and cancel the coroutines altogether without launching the activity.
To give more details, I’m building for Android, and I’m using CoroutineScrope
within the activity that is calling the method. I’m using launch
as it is used for most of the example code, and it looks like the only difference with async
is that async
cancels the parent and returns a deferred value. I also see that there are `CoroutineExceptionHandler`s, though I’m not sure if that is the right fit here.takahirom
09/18/2018, 2:04 AMkotlin
api.fetchPersons()
.subscribeOn(scheduler)
.subscribe(
{ persons ->
showPersons(persons)
},
{ e ->
showErrorDialog(e)
})
I enclosed with try catch to do the same on kotlin coroutines as follows.
But in this case CancellationException did not go to parents job, so I thought that it would be in an invalid state. Even if CancellationException is caught by the user, the outer block is not just canceled, is there no problem? Is it fine just like this?
kotlin
launch {
try {
val persons = api.fetchPersons() // suspend function
showPersons(persons)
} catch (e: Throwable) {
showErrorDialog(e)
}
}
louiscad
09/18/2018, 10:07 AMsuspend fun
? I'd like to see the approaches you prefergildor
09/18/2018, 10:11 AMNikky
09/18/2018, 10:58 AMvoddan
09/18/2018, 1:58 PMcoroutineScope { }
only inside another coroutine or a suspending function? What's wrong with fun main() = coroutineScope { <do the majic> }
? Do I need runBlocking{}
there? What's the meaning of runBlocking
with scoped coroutines if scopes wait for their children?Dico
09/19/2018, 2:42 AMcoroutineContext
is a top level property that can be accessed from suspend functions.
I suspect that it does this under the hood:
get() = suspendCoroutineUninterceptedOrReturn { cont -> cont.context }
aaverin
09/19/2018, 5:14 AMsuspend
function somehow find out in which dispatcher/executor is it running now?jovmit
09/19/2018, 11:38 AMVsevolod Tolstopyatov [JB]
09/19/2018, 3:24 PMkotlinx.coroutines
version 0.26.1
. Asynchronous Main dispatcher on Android, various bug fixes and improvements. See https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.26.1Harun
09/19/2018, 9:11 PMdanny
09/19/2018, 10:17 PM0.26.0
I see in the release notes that Dispatchers.Default
is now default dispatcher, but I had some existing code that was roughly runBlocking { someList.map { async { <do stuff with 'it'> } }.map { it.await } }
that previously ran on CommonPool
by default, but after the upgrade is constrained to the main thread. Guess I'm missing some detail around the structured concurrency changes...elizarov
09/20/2018, 6:40 AMcoroutineScope
. The launch
already provides one.bj0
09/20/2018, 4:33 PMCoroutineScope
object, is there a way to wait for it to finish (like coroutineScope
waits)?travis
09/20/2018, 6:33 PMDispatchers.Main
is added to the job
to make it so the dispatcher used for child coroutine builders will be Dispatchers.Main
(correct me if I'm wrong).
Which dispatcher is used if the + Dispatchers.Main
portion is omitted?
override val coroutineContext: CoroutineContext
get() = job
sdeleuze
09/21/2018, 8:25 AM0.26.1
seems available but not 0.26.1-eap13
, is that expected ?vaskir
09/21/2018, 9:20 AMfuture
function gone? There is no GlobalScope.future
.vaskir
09/21/2018, 9:30 AMelizarov
09/21/2018, 9:52 AMrx1
:yes: integration module on kotlinx.coroutines
release or can we just drop it 🇳🇴 and provide only rx2
integration? Please vote or tell your opinion in a thread.elizarov
09/21/2018, 9:52 AMrx1
:yes: integration module on kotlinx.coroutines
release or can we just drop it 🇳🇴 and provide only rx2
integration? Please vote or tell your opinion in a thread.alex2069
09/21/2018, 10:28 AM