Hi, there. I am writing a network library for And...
# coroutines
b
Hi, there. I am writing a network library for Android in Kotlin in which I used a lot of coroutines functionalities inside. So it’s possible to use the library from Java code, suspend functions are wrapped and hidden by callback base APIs. I found a really critical issue there. The problem happens when a user used the library with Future. If the client wrap the callback function with calling the get() method of Future in the UI thread,
delay
function call which is used inside the Library implementation never complete. As a result, Future.get() blocks forever. I know it’s not recommended to call Future.get() is not recommended practice. But, I would like to avoid this issue because it’s too disastrous given library clients has no idea if the
delay
suspend function is used under the hood. The following is the complete example code that reproduces the issue. https://gist.github.com/bananaumai/da23494ed2ba1d22c39af23a7c07ba2f#file-mainactivity-kt Any advise and/or recommendation would be appreciated. Thanks in advance.
n
If you have a main dispatcher, then that's the dispatcher used to wait for delays. This is not unique to
delay
. Any async library that uses the main thread would be blocked by someone calling
Future.get()
on the main thread. I don't think it's reasonable to assume that a Android library does not use the main thread.
call Future.get() is not recommended practice
"not recommended" is a bit of an understatement when it comes to blocking calls on the main thread.
👍 1
😇 1
😄 1
b
Thanks Nick. It totally makes sense. But, I’m still wondering why the similar code in the non-Android JVM environment behaves differently. On the JVM environment, the following code can complete. https://gist.github.com/bananaumai/da23494ed2ba1d22c39af23a7c07ba2f#file-main-kt
If you can give me some explanation, it would be appreciated 🙇 I’ll do some more experimentation any way.
n
I'm guessing on JVM you either don't have a main thread (you just use main) or, if you do, you are not calling get() on the main thread.
If there's no main dispatcher (or it doesn't implement the internal
Delay
interface) then a special executor is created specifically for delays. It's open source so when docs aren't enough, you can always dig through the source code.
b
I’m guessing on JVM you either don’t have a main thread (you just use main) or, if you do, you are not calling get() on the main thread.
Okay. Just for clarification. It was running in the main thread.
If there’s no main dispatcher (or it doesn’t implement the internal
Delay
interface) then a special executor is created specifically for delays.
It’s open source so when docs aren’t enough, you can always dig through the source code.
Sure. I’ll be looking into it. Thanks.
a
fwiw it looks like this behavior is slated to be changed in 1.6.1, https://github.com/Kotlin/kotlinx.coroutines/pull/3131
b
Hey, @Adam Powell ! Great information, thanks a lot! I was using 1.6.0, actually. I just switched down to 1.5.2, then the issue has disappeared!!! It must have been the issue in the PR.
I also tried the same code with the kotlinx-coroutines-core-jvm built from the head of develop branch. It worked as well.