I recall threads have problems with ios, but also ...
# multiplatform
c
I recall threads have problems with ios, but also coroutines weren't working that great (some month ago)
v
Probably coroutines. A 1.0 version of the kotlinx coroutines library was released about a month ago. I played with it for a bit and it worked fine on both Android & iOS.
t
The only limitation atm is that coroutines are single threaded on ios. So you can do things in parallel, just not on another thread.
k
Multiple options. I’m updating droidcon app to include coroutines on some ops, but have been backgrounding tasks for a while. There are two basic versions. One that just runs into the background and one that calls a return lambda https://github.com/touchlab/DroidconKotlin/blob/master/sessionize/lib/src/commonMain/kotlin/co/touchlab/sessionize/platform/Functions.kt
Only look at backgroundTask variants. The suspend ones are coming soon
We’re also using a port of LiveData (Android arch components) to listen to the dB by way of sqldelight and reload data for the ui. Reloading happens in whatever thread your dB op was on that triggered the reload, but pushes to main thread
This will all get a rethink when mt coroutines land, but for now, that’s some options
As for "single threaded corountes work fine", that depends what you're doing. The underlying operation should be async. In the example of ktor, it suspends you, but the NSSession system underneath is doing work, and "wakes up" the suspended operation when it's done. If you're doing something blocking, you can suspend the caller while that's happening, but you're still occupying the thread (and the rest of the UI is not). So, depends.
t
Can you rephrase that in a simpler manner, as I really would like to understand it? 🙂
k
That's a blog post I've started multiple times, but let me see if I can...
t
And I am still waiting for that blog post 😆
k
Ultimately, if you're doing "work" it's occupying a thread
Traditionally (ie. not coroutines), to do background work, your code needs to "kick off" something on another thread, and in order to release the thread you're on, your code needs to "exit".
Coroutines let you stop what you're doing, and let it resume later. While that "stop" happens, other parts of the system can use the thread
t
yep, using the continuation concept.
k
In the case of mobile (and other systems), you have the "main thread" and "everything else". Single threaded coroutines will generally run in the main thread (or at least in the examples we have now)
In the case of ktor, for example, you call ktor in your code on the main thread, ktor "kicks off" an async process with the ios system to do network calls, and suspends.
At that point, the main thread is free to do whatever else it needs to do
When the network calls finish, the ios system "wakes up" ktor, which ultimately returns to your original call
Under the hood, that all has to get scheduled on the main thread using ios's usual mechanisms
It is "seamless" to you, but while network calls happened, there was a lot of room for the main thread to service your UI (and whatever else)
Now, if you write a suspending op, you need to handle that stuff. If instead of ktor, you decide to write a library that does something similar, and you have an operation that takes about 10 seconds (lets say), if you set it up such that you suspend the caller, but you still do all of your work in the main thread, you're blocking the main thread. The key is the async operation
It is not trivial to set that up properly
I am attempting to do that in the Droidcon app also
On ios it would kick off a process in a Kotlin/Native Worker, and suspend the caller while that happens https://github.com/touchlab/DroidconKotlin/blob/master/sessionize/lib/src/commonMain/kotlin/co/touchlab/sessionize/platform/Functions.kt#L32
Waking back up has been tricky. I am currently trying to finish a sqlite driver for sqldelight, after which I'll get back to Droidcon. Ran into some other issues finalizing that, but I think we're there: https://github.com/square/sqldelight/pull/1087
Anyway, so, if you suspend the caller and do work on the main thread, but it's "short" work, you won't notice much of an issue, even though coroutines aren't buying you much. To get any real benefit from single threaded coroutines, you need to figure out how to suspend and offload significant work.
t
Okay, guess I gotcha. The challenge is basically after suspending the main thread, doing things in an async manner using either the kotlin/native concurrency model or any native ios api, and coming back to free it.
Gonna have a look at the PR, thanks for taking the time to explain it 👍
k
Don't look at the sqldelight pr. that's just my excuse for not finishing droidcon
For suspending, when you call 'suspendCoroutine', you get a Continuation param, which you can store and call to resume later (https://github.com/touchlab/DroidconKotlin/blob/master/sessionize/lib/src/commonMain/kotlin/co/touchlab/sessionize/platform/Functions.kt#L22, and line 26)
However, you can't call resume from another thread, so the Continuation instance needs to stay in the main thread
t
ahhh
k
That's the trick
You can't freeze it
t
ok
that makes sense
k
I got it working in a simplified example, but didn't quite get my more involved 'backgroundTask' version working. I'm 95% sure it's something dumb I'm doing, but debugging native is tough, multithreaded native very tough
Also, not a lot of incentive. Whenever MT coroutines land, all of that work gets tossed.
👍 1
You're at Novoda? Say hi to Kevin and Carl!
t
Yep, will do 🙂
c
hey kevin, what "MT coroutines" are? btw thanks for that recap about threading with mpp 🙂
k
Multi-Threaded
c
damn I feel so dumb 😂 sorry for the stupid question