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

elizarov

05/18/2017, 9:28 PM
@groostav with
kotlinx-coroutines-jdk8
you can write something like:
Copy code
val coercedResult = future { 
    try { result.await() } 
    catch(ex: Throwable) { 
        Thread.handleUncaughtException(ex)
        emptyList() 
    } 
}
😀 1
g

groostav

05/18/2017, 9:49 PM
elizarov: out of curiosity, if
coercedFuture
was a
var
, can you write
coercedFuture = future { coercedFuture.await() }
. It should right? The closure isn't going to capture changes in stack variables.
actually this can be trivially tested...
e

elizarov

05/18/2017, 9:55 PM
Kotlin closures caputure vars as mutable vars
Kotlin closures behave just like other
{ ... }
block. If you mutate something from there, it mutates.
g

groostav

05/18/2017, 9:56 PM
yeah, so that makes the code I wrote a kind of descheduled deadlock. Can a CoroutineContext provide enough info for cycle detection?
e

elizarov

05/18/2017, 9:57 PM
can you elaborate on your problem?
g

groostav

05/18/2017, 9:58 PM
Copy code
@Test fun `when using mutable stack future var should properly snapshot in closure`(){
        //setup
        val initial = CompletableFuture<Int>()
        var ref = initial
        ref = future {
            ref.await() !!!! //this code deadlocks!
        }

        //act
        initial.complete(42)
        val result = ref.get()

        //assert
        assertThat(result).isEqualTo(42)
    }
causes deadlock
Im not thinking about a problem so much as a gotcha for newbies
im wondering if coroutines can programatically detect this behaviour, but I suppose that would only work for the
future
and
await
methods, not simply all coroutines generally
e

elizarov

05/18/2017, 10:03 PM
it is hard to detect programmatically
even Go is bad at detecting stuff like that
also `var`s are evil.
g

groostav

05/18/2017, 10:04 PM
yeah i know, but its a supported language feature, somebody is going to write production code like I just sent you
and be suprised by a deadlock
e

elizarov

05/18/2017, 10:04 PM
there is plan
g

groostav

05/18/2017, 10:04 PM
I'm also thinking a
CoroutineContext
check at the
future
and
await
boundaries should be sufficient
e

elizarov

05/18/2017, 10:06 PM
Coroutines are not like threads. They don't even have ids. But in debug mode they do, so we might try to write some kind of dead-lock detector based on that.
g

groostav

05/18/2017, 10:06 PM
something like
Copy code
fun future(ctx: CoroutineContext){
  val newContext = newCoroutineContext(CommonPool + context + BlacklistFuture(future))
  //...
}
fun Future.await() {
  if(this in currentContext.blacklistedFutures.map { it.future) throw IllegalStateException("cyclic call to future!")
}
e

elizarov

05/18/2017, 10:07 PM
This is an interesting idea. Could work!
There also an IDE proposal to warn on that kind of
var
-capturing code: https://youtrack.jetbrains.com/issue/KT-15514
g

groostav

05/18/2017, 10:08 PM
yeah its funny, I was driven nuts once or twice by java's "variable must be effctively final", but I suppose this is simply the other side of that coin
e

elizarov

05/18/2017, 10:11 PM
Exactly
3 Views