-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DRAFT] Support sharing of coroutines across threads in Kotlin/Native #1648
Conversation
cc400ce
to
9e975d8
Compare
I’ve published the first development preview version of multi-threaded |
|
Thanks! Added test with reproducer and fixed. |
I've squashed all the changes so far into a single commit making it easier to keep it rebased on top of the |
I've been running into an issue related to state freezing and coroutines. Essentially, if freezing fails inside the "machinery" of coroutines, we can get into a weird state. Here's a basic example. @Test
fun freezeFail() = runBlockingTest {
assertFails {
returnState()
}
}
suspend fun returnState() = withContext(stateDispatcher) {
val sd = SomeData("arst")
sd.ensureNeverFrozen()
sd
}
data class SomeData(val s: String)
I would expect an exception to be thrown from For reference, this "works" as expected... suspend fun returnState() = withContext(stateDispatcher) {
val sd = SomeData("arst")
throw IllegalStateException("just testing")
// sd.ensureNeverFrozen()
sd
} The There is an exception written to the console
kotlinx.coroutines is a local build that is up to |
It's been a while since there's been an update. I'm not sure if this will even be relevant now, but I've run into an issue where same-thread results are unfrozen until you run an operation on another thread and return a frozen result. From then on, using the same scope, same-thread operations return frozen results. Presumably this is due to using Here's a basic example: fun goMain() = mainScope.launch {
val result = withContext(Dispatchers.Main){
SomeData2("236")
}
println("Main isFrozen ${result.isFrozen}")
}
fun goBackground() = mainScope.launch{
val result = withContext(Dispatchers.Default){
SomeData2("125")
}
println("Default isFrozen ${result.isFrozen}")
}
data class SomeData2(val s:String) Two methods:
When you call
This by itself isn't a huge issue, but it made ktor unusable with the same scope. As a workaround, we created 2 scopes, and reserve 1 for ktor only. Not ideal, but workable for now. I'm assuming the Our test scope here looks like this: class ModelScope(private val mainContext: CoroutineContext) : CoroutineScope {
internal val job = Job()
private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
println("error $throwable")
throwable.printMe()
}
override val coroutineContext: CoroutineContext
get() = mainContext + job + exceptionHandler
} My expectation is that the same-thread behaviour would be consistent. Either always freeze or never freeze. I was surprised to have it act differently after calling another thread. Not sure how feasible that would be to implement, though. Ktor was obviously not designed or tested to work with the MT preview version of coroutines, so it's not a huge surprise that we ran into issues. |
Hi, I am experiencing some issues with the Flow combine operator. The following code will throw an exception when running on Mac OS: package sample
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlin.native.concurrent.*
fun main() {
runBlocking {
MyViewModel()
delay(2000)
}
}
class MyViewModel {
val mainScope = CoroutineScope(Job() + Dispatchers.Default)
init {
ensureNeverFrozen()
mainScope.launch {
val flow = flowOf("string")
combine(flow, flow) { a, b -> a to b }
.collect {
println("this is never reached")
}
}
}
}
I don't think this is supposed to happen. It only happens with the combine operator for me, so I think that is the issue. The sample crashes for me with version |
Hi, I want to know when could this feature been release, any plan for this? |
6ef8a5e
to
2ae053d
Compare
4a49830
to
aff8202
Compare
Please publish 1.3.4-native-mt |
Sorry, we cannot. It cannot be built with Kotlin |
46f7abd
to
9d03705
Compare
8df9c27
to
48cf2cf
Compare
e0f92a6
to
386640c
Compare
58811d5
to
17e0fc9
Compare
The latest Ktor release at this time is built with
See for more information: https://kotlinlang.slack.com/archives/C0A974TJ9/p1640280717189900 |
@Thomas-Vos try using the version of Ktor mentioned here: https://github.com/JetBrains/kotlin/blob/master/kotlin-native/NEW_MM.md#update-the-libraries |
@dkhalanskyjb thanks, but that would not work for me. I am using Ktor 2.0.0 specific features (UDP sockets) so I am stuck with the 2.0.0 releases. |
1ee4f5d
to
ce57d59
Compare
* 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. * Fix ObjC autorelease object leaks with native-mt dispatchers (#2477) 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 Fixes #2322 Fixes #2283 Fixes #2688 Fixes #2398 Fixes #3136
Work in progress.