30

I'm curious about the internal working of a coroutine when suspended on the main thread. The real question is how to log a suspended function which is a coroutine on the main thread. Where exactly the execution is taking place? Is it a virtual thread?

4 Answers 4

42

If you are talking about logging the coroutine name:

You can achieve this by

  1. Give name to coroutine(if you want custom name): launch(CoroutineName("My-Coroutine"))

  2. Enable the logging in IntelliJ toolbar menu: Run -> Edit Configuration and add

-Dkotlinx.coroutines.debug in VM options.

VM Option in Edit Configuration

Then you can see @My-Coroutine in logcat.

Try below code after Edit Configuration change:

fun main() = runBlocking {
println("   'runBlocking': I'm working in thread ${Thread.currentThread().name}")

val job = launch(CoroutineName("my-custom-name")) {
    println("   'runBlocking': I'm working in thread ${Thread.currentThread().name}")

}

job.join()}

Result: Result

Sign up to request clarification or add additional context in comments.

2 Comments

How to do the same for multiplatform and/or Native?
Where is Vm Options? I used Android Studio 4.1.1 and in Run/Edit configuration..only found VmOptions inTemplates/kotlin. Is that the same you mean?
13

The other answers don't answer the question directly "How to get the name of a coroutine in Kotlin?"; instead, they suggest how to name a coroutine.

If inside a coroutine, the name can be retrieved using currentCoroutineContext()[CoroutineName].

If outside a coroutine, there's no direct way to retrieve the name using a reference to a Job or Deferred (too bad). However, there's a reflection hack that can be used. Of course, the usual warnings come attached, which are, no type safety and hacking into internal APIs that may change anytime.

@Suppress("UNCHECKED_CAST")
val nameString = AbstractCoroutine::class.memberFunctions
    .single { it.name == "nameString" } as Function1<AbstractCoroutine<*>, String>
val name = nameString(job as AbstractCoroutine<*>)
    .replace("\"", "")
    .takeWhile { it != '#' }

The method/function containing this code has to be marked with @InternalCoroutinesApi.

Comments

6

You can give name to coroutine using CoroutineName(name:String) method at the time of creating coroutine:

repeat(5) {
            GlobalScope.launch(CoroutineName("$it")) {
                displayGreetingsFor(it)
            }
        }

To retrive the name given to coroutine use coroutineContext[CoroutineName.Key] as shown below:

private suspend fun displayGreetingsFor(i: Int) {
        delay(100)
        println(
            " ${coroutineContext[CoroutineName.Key]} is executing on thread : ${Thread.currentThread().name}"
        )
    }

This is will print following o/p on console:

CoroutineName(0) is executing on thread : DefaultDispatcher-worker-3
CoroutineName(1) is executing on thread : DefaultDispatcher-worker-2
CoroutineName(2) is executing on thread : DefaultDispatcher-worker-8
CoroutineName(3) is executing on thread : DefaultDispatcher-worker-6
CoroutineName(4) is executing on thread : DefaultDispatcher-worker-5

1 Comment

Don't encourage usage of GlobalScope by including that in your answer.
6

You can use CoroutineName("some name") as others have mentioned

To print CoroutineName, there are 3 ways:

Method A

System.setProperty("kotlinx.coroutines.debug", "on" ) will make Job.toString() include the name

e.g.

"my coroutine#4":StandaloneCoroutine{Active}@b735e2c

Method B

Inside each scope, printing the CoroutineContext.toString() will include the name

e.g.

CoroutineContext: [CoroutineName(my coroutine), StandaloneCoroutine{Active}@b735e2c, DefaultDispatcher]

Method C

Quite similar to method B, for Job objects, we can print (Job as CoroutineScope).coroutineContext.

Take note that (Job as CoroutineContext) does NOT work! (not sure why but (Job as CoroutineContext).get[CoroutineName] returns null)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.