how to use runBlocking if at all? Its an intellij ...
# getting-started
s
how to use runBlocking if at all? Its an intellij plugin, we have a situation that runBlocking hangs forever, i have a function that starts a coroutine
Copy code
parentDisposable.disposingScope().launch {
    while (isActive) {
        environment.refresEnvironments()
        delay(60000)
    }
}
this function calls legacy java code ,kotlin code etc. somewhere in the call stack we catch authentication exception from a call to our api and we refresh the authentication token, then we need to call a suspend function, we have a function similar to this:
Copy code
@Synchronized
fun onAuthenticationException() {
   ...  refresh the token
   updateAccount(account,credentials)
}

fun updateAccount(account: Account, credentials: Credentials) {
    runBlocking {
        AccountManager.getInstance().updateAccount(account, credentials)
    }
}
AccountManager.getInstance().updateAccount is suspend function so must call it from suspending block and we use runBlocking. sometimes this runBlocking just hangs forever, looking at the code it probably does LockSupport.parkNanos with Long.MAX_VALUE the runBlocking actually runs on the coroutine that started the flow with environment.refresEnvironments() is there something in our code that is wrong? should we do something else then runBlocking ? is the fact that onAuthenticationException is @Synchronized has a bad impact on runBlocking ? is it because runBlocking runs in the context of another coroutine ? this is a part of a thread dump "DefaultDispatcher-worker-18" #20610 daemon prio=5 os_prio=31 cpu=1041.73ms elapsed=6012.47s tid=0x00000003af0d5c00 nid=0x42507 waiting on condition [0x00000002b28c0000] java.lang.Thread.State: TIMED_WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@17.0.11/Native Method) - parking to wait for <0x00000007c72a6460> (a kotlinx.coroutines.BlockingCoroutine) at java.util.concurrent.locks.LockSupport.parkNanos(java.base@17.0.11/LockSupport.java:252) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:88) 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 org.digma.intellij.plugin.auth.AuthutilsKt.updateAccount(authutils.kt:20) at org.digma.intellij.plugin.auth.AuthApiClient.refreshToken(AuthApiClient.kt:53) - locked <0x00000007c72a64b0> (a org.digma.intellij.plugin.auth.AuthApiClient) at org.digma.intellij.plugin.auth.LocalLoginHandler.loginOrRefresh(LocalLoginHandler.kt:84) at org.digma.intellij.plugin.auth.AuthManager.onAuthenticationException(AuthManager.kt:152) - locked <0x00000007865eb640> (a org.digma.intellij.plugin.auth.AuthManager) at org.digma.intellij.plugin.auth.AuthManager.access$onAuthenticationException(AuthManager.kt:27) at org.digma.intellij.plugin.auth.AuthManager$MyAuthInvocationHandler.invoke(AuthManager.kt:244) at jdk.proxy8.$Proxy118.getEnvironments(jdk.proxy8/Unknown Source)
s
is it because runBlocking runs in the context of another coroutine
Yes, that's almost certainly the reason.
s
Thanks, you have a suggestion how to run this code blocking without using runBlocking? maybe run async and wait on deffered ?
s
The only safe way for a coroutine to wait for a suspending function is to suspend the coroutine. The reason is that the called function may try to dispatch work to the thread/dispatcher you're currently running on. So your options are to make
onAuthenticationException
(and all its callers) be a suspending function, or accept that it won't be able to safely wait for
updateAccount
to complete.
s
OK, now I understand. I will figure out how to do it. Thank you