Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGitHub is where the world builds software
Millions of developers and companies build, ship, and maintain their software on GitHub — the largest and most advanced development platform in the world.
Support multi-threaded coroutines on Kotlin/Native #462
Comments
Do you have a ballpark time frame for implementing this (days, weeks, months, ...)? This will help me plan how to implement the first revision of our project. Thanks! |
Second that. Can we please get a rough estimate? |
We're in the design phase now. I'll update you on the status in couple of weeks. |
Have any progress? |
We have a work-in-progress branch in this repo with some of the code that is implemented, but it is way too complex a change, so the work there was stopped. It is hard to get it done in the current state. We've refocused our efforts on delivering high-quality single-threaded coroutines which work really well for sharing logic between Android and iOS UI apps (I highly recommend to checkout the code of KotlinConf app here https://github.com/JetBrains/kotlinconf-app). With respect to multithreading, we'll be back to drawing board to see how this story can be made easier to code with. Don't expect results soon, though. |
Does this mean it can already work without runBlocking, i.e. with launch?
Because that's really something I'd like to advantage of to make
multiplatform UI contracts.
…On Thu, Oct 11, 2018, 11:03 PM Roman Elizarov ***@***.***> wrote:
We have a work-in-progress branch in this repo with some of the code that
is implemented, but it is way too complex a change, so the work there was
stopped. It is hard to get it done in the current state. We've refocused
our efforts on delivering high-quality single-threaded coroutines which
work really well for sharing logic between Android and iOS UI apps (I
highly recommend to checkout the code of KotlinConf app here
https://github.com/JetBrains/kotlinconf-app). With respect to
multithreading, we'll be back to drawing board to see how this story can be
made easier to code with. Don't expect results soon, though.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#462 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGpvBbJNoE1CfiTsRyODDVV-FqOf-diVks5uj7ITgaJpZM4VjGFc>
.
|
Yes, it works without |
@elizarov Trying to convert Waiting for a job example to work without run blocking using (#470 (comment)) in a native macOs program. But I am still getting I've tried starting the loop like:
But I don't think I'm doing that correctly, any ideas? |
@luca992 please use
|
@qwwdfsad I know that it works with run blocking... Are you saying it is only possible to run without runBlocking on iOS for some reason? Edit: |
Is there any solution to support MultiThreaded coroutines yet? IMHO, It's nearly impossible to implement a multi-threading coroutine dispatcher under current Kotlin/Native threading model. Should we redesign the threading model? Maybe it is good for writing rebust code that, Kotlin/Native implement Lock/Thread/ThreadPool, and use those tools to implement coroutine. For those just want to offload jobs to different thread, it is good enough to use coroutine. And for those who cares very much about performace, give them the ability to use raw thread/thread pool. For example, to write a high performance low latency audio app, one usually create threads with the hieghest scheduling proiorty, and event bind those threads to a certain cpu core to eliminate context switch. |
Current my solution is to totally move the threading part into native ios code. like this. private val requestingHashMap = hashMapOf<String, IosHttpGetAgent.Callback>()
fun notifyHttpGetResponse(url: String, result: String?, error: String) {
requestingHashMap.remove(url)?.onGetResult(url, result, error)
}
@Throws(IOException::class)
actual suspend fun httpGet(url: String): String {
return suspendCoroutine { continuation ->
val cb = object : IosHttpGetAgent.Callback {
override fun onGetResult(url: String, result: String?, error: String) {
if (result != null) {
continuation.resume(result)
} else {
continuation.resumeWith(Result.failure(IOException(error)))
}
}
}
requestingHashMap[url] = cb
iosHttpGetAgent.value!!.httpGet(url)
}
} While on the swift code. func httpGet(url: String) {
let task = URLSession.shared.dataTask(with: URL(string: url)!) { (data, response, error) in
if let resultData = data {
DispatchQueue.main.async {
ActualKt.notifyHttpGetResponse(
url:url,
result: String(data: resultData, encoding: .utf8)!,
error: "success")
}
} else {
DispatchQueue.main.async {
ActualKt.notifyHttpGetResponse(
url:url,
result: nil,
error: "success")
}
}
}
task.resume()
} So kotlin/native code runs totally on the main thread. |
Running totally on the main is the only solution for now. You can track #829 which will slightly expand your options and you'll be able to run coroutines separately on each threads (no easy way to communicate, though). |
Hi, any progress on this issue? Or any possible solution for this issue? @elizarov |
I'm also very concerned about this. |
Well, the current state of multithreading in K/N is not really suitable for coroutines, the simple fact of giving a Continuation to a worker freeze the continuation, thus freezing the captured state and making it immutable (and pretty much unsuable). For me multithreded coroutines is simply impossible with the current model. |
@SeekDaSky I am not very experienced with K/N's concurrency model nor with the way, coroutines work under the hood, but I would also want to see support for multi-threaded coroutines in K/N. |
If I understand correctly you could detach the continuation and keep it mutable, but the state would not be accessible from another worker, so we still can't share values between threads. We could heavily use channels and the actor paradigm to avoid any variable being shared, but this could lead to some performance degradation. And this is just the developper side, developing a dispatcher with the limitations of the current concurrency model probably is daunting. |
No, this might be pretty naive, but wouldn't it be possible to capture the whole state of the coroutine in some structure (let's say a data class) and just pass a new copy to the next worker? |
To achieve this I think you just have to detach the continuation and re-attach it inside the next worker but you still can't have two threads accessing the data at the same time. And this could lead to some weird side effect if you share a value between two continuations by mistake |
Would you mind explaining this a little? I would be super interested |
@SvyatoslavScherbina thanks, have created https://youtrack.jetbrains.com/issue/KT-40782 |
Do we have any change log and doc for 1.3.8-native-mt-1.4.0-rc build? |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job) and all kinds of channels are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 ~ Kotlin 1.4-M2-eap-83
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job) and all kinds of channels are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 ~ Kotlin 1.4-M2-eap-83
1.3.9-native-mt is here: mirror of 1.3.9 with the same changes in Native part as in previous |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job) and all kinds of channels are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025
Do you have any plan for a new native-mt version including fix #2025? |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138
1.3.9-native-mt-2 was released and ktor is working without any problem on native target. |
Anybody has any idea why this issue exists in the mt version? #2335 runBlocking is not the only problem, I also witnessed code not being executed in main code. In particular with nested withContext() blocks. |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
I filed this report https://youtrack.jetbrains.com/issue/KT-42898 which I am a bit surprised no one else is running into. Basically, what happens is that a child coroutine returning a new instance of a class causes that instance to be frozen, even when all coroutines run on the same thread. I wouldn't expect this. Perhaps I'm doing something stupid. Would be awesome if someone on the team could have a quick look and determine whether this is just me or an actual bug. |
May I have an ETA on a As it's been two week since Thanks |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
UPDATE: |
Does this also fix this issue https://youtrack.jetbrains.com/issue/KT-38770 ? Haven't tested it myself yet but am planning to do that tomorrow. Will update this thread with my results. |
I might be missing something, when I create a MutableStateFlow but set the value I get an InvalidMutabilityException. The same code worked in 1.3.9. Has anyone else ran into issues? |
@TrevorStoneEpic others are experiencing that issue as well, looks like #2138 was re-opened and is tracking it. |
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
* Provides newSingleThreadedContext. * Provides Dispatchers.Main on iOS, Dispatchers.Default everywhere. * Coroutine references (Job), all kinds of channels and StateFlow are shareable across workers. * Each individual coroutine is confined to a single worker. * Update Dispatchers docs to account for native-mt changes. * Multithreaded support in select expression. Additional fixes: * Fixed broadcast builder with different thread * Fixed adding a child to a frozen parent job Fixes #462 Fixes #470 Fixes #765 Fixes #1645 Fixes #1751 Fixes #1828 Fixes #1831 Fixes #1764 Fixes #2064 Fixes #2025 Fixes #2226 Fixes #2138 Fixes #2263
Released 1.4.2-native-mt |
You can have multiple threads in Kotlin/Native.
Each thread can have its own event loop with. Currently communication between those threads via coroutine primitives (like channels) is not supported. This issue it to track enhancement of Kotlin/Native inrunBlocking
and have number of coroutines running therekotlinx.coroutines
library so that all the following becomes possible:UPDATE: Currently, coroutines are supported only on the main thread. You cannot have coroutines off the main thread due to the way the library is currently structured.