Hello. If somebody interested in `coroutines-inter...
# reaktive
a
Hello. If somebody interested in
coroutines-interop
with mt coroutines, please check https://github.com/badoo/Reaktive/issues/304 It should be possible to publish a separate version. Please vote and/or respond. 🤘🚀
👍 2
m
Hi @Arkadii Ivanov, will this enable us to do Ktor calls in background threads?
It gets a bit confusing when we mix them together and I know you recommend not to use
singleFromCoroutine
with Ktor since it causes issues.
a
Hey @Mina Eweida, unfortunately no, Ktor is still not compatible multithreading. But it will be possible to use Ktor in main-thread-only environment. Same as it is now currently, with copy-pasting the "unsafe" solution. So basically "unsafe" will become safe in terms of coroutines themselves. But Ktor is still main thread only.
m
😞
a
Yeah. The future of Ktor is really unclear to me. There is an issue you can follow for tracking: https://youtrack.jetbrains.com/issue/KTOR-499 Also there is a roadmap for the next year, and there is nothing about the problem there: https://blog.jetbrains.com/ktor/2020/08/10/ktor-roadmap-for-2020-2021/
m
I know you don’t recommend it but we were able to work around this with Reaktive by running blocking inside a
singleFromFunction
. Which is not a clean solution but it works. i.e. we did this
Copy code
singleFromFunction {
    singleFromCoroutine {
         doYourKtorCallHere()
    }.blockingGet()
}
The problem was Ktor is not freezing exceptions, so if you get an error with the network call it will crash on native so to fix that we did the following
Copy code
singleFromFunction {
    try {
        singleFromCoroutine {
             doYourKtorCallHere()
        }.blockingGet()
    } catch (throwable: Throwable) {
    throw throwable.freeze()
}
}
This can be fixed by freezing throwables on Ktor side though, but so far this has been working fine in production for us
a
This is how singleFromCoroutine works under the hood currently in Native. It executes the callback in runBlocking. So you have to subscribeOn(ioScheduler). And it should make Ktor crash.
m
we do subscribe on io!
Copy code
singleFromFunction {
    try {
        singleFromCoroutine {
             doYourKtorCallHere()
        }.blockingGet()
    } catch (throwable: Throwable) {
    throw throwable.freeze()
}
}.subscribeOn(ioScheduler)
so we switch to io, then runBlocking. This does not crash for us
a
So I believe you could just use singleFromCoroutine?
Or just runBlocking insider singleFromFunction
But it should crash from time to time
m
do you mean singleFromCoroutine.subscribeOn(ioScheduler).blockingGet()?
a
No need for blockingget
singleFromCoroutine { /* * This block will be executed inside
runBlocking
in Kotlin/Native. * Please avoid using Ktor here, it may crash. */ } .subscribeOn(ioScheduler) .observeOn(mainScheduler) .subscribe { /* Get the result here */ }
So you CAN use Ktor, but it may crash
Also observeOn freezes exceptions under the hood
m
Wow
I am checking for crashes to be sure, any idea what kind of crashes that might be caused by ktor? Because I checked our iOS app and we don’t have crashes related to ktor but maybe I missed it because it does mention Ktor in the crash
a
Basically Ktor uses top level properties without any annotations, which is possible only on main thread. And also HttpClient is not freezable. But maybe something was fixed. Also you might be handling errors with onError callback. So there is no crash, but just a normal error?
m
oh yeah sorry I remembered now, the non clean solution we did was we instantiate a new client with every network call, since our feature was basically just a post request we could afford to provide a new client with every call because as you said correctly, the client gets frozen and network calls involves some mutation.
Of course we
use
the client so that it does not get leaked
a
Yeah. But in my cases Ktor did not work even when creating a new HttpClinet every time. Because it was using top level properties and they were not allocated with SharedImmutable nor ThreadLocal. But maybe this changed...
I will check this later, and if it's fixed then good. But I am not sure about my coroutines as well. It may still crash.
m
yeah maybe because doing a single call is never an issue with us, the problem with a single client (aside from the fact that we are providing a new client with each call 😄 ) is that we cannot have caching because probably Ktor is doing that in memory and per client so we cann’t share cache between different clients so for get requests that we need to cache this solution won’t work with it (unless you do your own caching instead)
a
Yep. As I said I was not able to use Ktor at all. Even when I was creating a new client per request. It was crashing from time to time. Like very flaky.
So maybe good for pet projects, but really not acceptable for real production apps.
m
👍
o
So true, we ended up replacing it with expect/actual (OkHttp, NSURLSession and window.fetch), IDK if it's worth to OSS it