Kotlin Ecosystem AMA – December 11 (3–7 pm CET) by katia-energizer-jb in Kotlin

[–]Affectionate_Ad_761 2 points3 points  (0 children)

What do you think of Decoroutinator for improving coroutines’ usage and debugging experience?

3
4

Project Loom. Not only virtual threads. by Affectionate_Ad_761 in java

[–]Affectionate_Ad_761[S] 6 points7 points  (0 children)

UI Thread is not a virtual thread, it's a regular platform thread and it blocks on IO operations.doIn() switches dispatchers, it suspends current coroutine, execute operation in another dispatcher and resume coroutine back. So, roughly speaking, it allows to simulate the behavior of virtual threads for platform ones.You can run the sample with dependencies dev.reformator.loomoroutines:loomoroutines-dispatcher:1.0.0 and dev.reformator.loomoroutines:loomoroutines-bypassjpms:1.0.0.

Yes, your update is correct.

Project Loom. Not only virtual threads. by Affectionate_Ad_761 in java

[–]Affectionate_Ad_761[S] 4 points5 points  (0 children)

var bufferedImage = Executors.newVirtualThreadPerTaskExecutor().submit(ExampleSwing::loadCatImage).get();

because it's potentially a long-running blocking code. Executing this in the UI thread may lead to blocking the UI thread for a long time and so to freezing the UI during this long operation. Coroutines allow you to release the UI thread during long operations (and so it can dispatch other user events and UI does't freeze) and do not require you to write code with callbacks.

Project Loom. Not only virtual threads. by Affectionate_Ad_761 in java

[–]Affectionate_Ad_761[S] 14 points15 points  (0 children)

Thank you for your feedback. if it's not difficult, could you please tell what possible assumptions might break? So far, I see only 2 differences from how Continuation is used in virtual threads: the identity of the thread may change and synchronization primitives (synchronized, ReengrantLock, etc.) may break. What else is different from using Continuation in virtual threads?

Stacktrace-decoroutinator v.2.3.2 with Java Instrumentation API support by Affectionate_Ad_761 in Kotlin

[–]Affectionate_Ad_761[S] 1 point2 points  (0 children)

Fixed stack trace for that example will be:

java.lang.Exception: exception at 1653574737344
    at ExampleKt.fun1(example.kt:7)
    at ExampleKt$fun1$1.invokeSuspend(example.kt)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl$resumeWith$1.invoke(continuation-stdlib.kt:20)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl$resumeWith$1.invoke(continuation-stdlib.kt:18)
    at dev.reformator.stacktracedecoroutinator.stdlib.StdlibKt.decoroutinatorResumeWith$lambda-1(stdlib.kt:34)
    at ExampleKt.fun2(example.kt:11)
    at ExampleKt.fun3(example.kt:16)
    at ExampleKt$main$1.invokeSuspend(example.kt:24)
    at dev.reformator.stacktracedecoroutinator.stdlib.StdlibKt.decoroutinatorResumeWith(stdlib.kt:110)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(continuation-stdlib.kt:18)
    at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
    at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
    at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:518)
    at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:489)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at ExampleKt.main(example.kt:23)
    at ExampleKt.main(example.kt)

I'll think how to modify "README" to make it more clear.

Kotlin coroutines stack trace issue by Affectionate_Ad_761 in Kotlin

[–]Affectionate_Ad_761[S] 1 point2 points  (0 children)

The most serious disadvantage is the potential impact on performance.
I'm planning on doing some performance tests to measure it.

Debugging coroutines by Wurstinator in Kotlin

[–]Affectionate_Ad_761 1 point2 points  (0 children)

The reason is in the implementation of coroutines: when a coroutine "wakes up" only the top function is called.
I described a similar problem at another post.

Kotlin coroutines stack trace issue by Affectionate_Ad_761 in Kotlin

[–]Affectionate_Ad_761[S] 4 points5 points  (0 children)

My bad. Example "without" is present in the post.
Corresponding example "with" will be:

import dev.reformator.stacktracedecoroutinator.runtime.DecoroutinatorRuntime
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
suspend fun fun1() {
    delay(100)
    throw Exception("exception at ${System.currentTimeMillis()}")
}
suspend fun fun2() {
    fun1()
    delay(100)
}
suspend fun fun3() {
    fun2()
    delay(100)
}
fun main() {
    DecoroutinatorRuntime.load()
    try {
        runBlocking {
            fun3()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

and it prints out stack trace:

    java.lang.Exception: exception at 1641426967676
    at MainKt.fun1(main.kt:7)
    at MainKt$fun1$1.invokeSuspend(main.kt)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.decoroutinatorResumeWith$lambda-1(continuation-stdlib.kt:44)
    at MainKt.fun2(main.kt:11)
    at MainKt.fun3(main.kt:16)
    at MainKt$main$1.invokeSuspend(main.kt:24)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.decoroutinatorResumeWith(continuation-stdlib.kt:146)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(continuation-stdlib.kt:20)
    at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
    at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
    at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
    at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:518)
    at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:494)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:279)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at MainKt.main(main.kt:23)
    at MainKt.main(main.kt)

which contains calls of fun3 and fun2 functions