ktor: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.StandaloneCoroutine@28a82d8
works on android, breaks on ios
code:
fun triggerNetworkCall(){
GlobalScope.apply {
launch(Background) {
try {
val data = repository.getSettings()
} catch (t: Throwable) {
Logger.d("ktor", t.message?:"null")
}
}
}
}
suspend fun getSettings(): String? {
val response = apiConfig.getReferralData()
return response
}
suspend fun getReferralData(): String? {
val localClient = HttpClient(PlatformHttpClient.httpClientEngine){
install(JsonFeature)
}
return localClient.post {
url {
protocol = URLProtocol.HTTPS
host = "postman-echo.com"
encodedPath = "post"
}
contentType(ContentType.Application.Json)
body = "{}"
HttpMethod.Post
}
}
This post request works in android but fails in iOS with following stack trace:
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.StandaloneCoroutine@1a8b4e8
whereas a get request works on both platforms. Following is the function being used:
suspend fun getReferralData(): String? {
val localClient = HttpClient(PlatformHttpClient.httpClientEngine){
install(JsonFeature)
}
val address = Url("https://postman-echo.com/get?foo1=bar1&foo2=bar2")
return localClient.get {
url {
url(address.toString())
}
}
}
Dispatchers definition: iOS
internal actual val Main: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
internal actual val Background: CoroutineDispatcher = Main
internal class NsQueueDispatcher(
private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatchQueue) {
block.run()
}
}
}
android
internal actual val Main: CoroutineDispatcher = Dispatchers.Main
internal actual val Background: CoroutineDispatcher = Dispatchers.Default
dependencies
commonMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:1.3.61"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:0.14.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.3.2-1.3.60"
implementation "co.touchlab:stately:0.9.4"
implementation "co.touchlab:stately-collections:0.9.4"
implementation "io.ktor:ktor-client-core:1.2.6"
implementation "io.ktor:ktor-client-json:1.2.6"
implementation "io.ktor:ktor-client-logging:1.2.6"
implementation "io.ktor:ktor-client-serialization:1.2.6"
implementation "com.github.aakira:napier:1.1.0"
}
}
androidMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.2-1.3.60"
implementation "io.ktor:ktor-client-core-jvm:1.2.6"
implementation "io.ktor:ktor-client-json-jvm:1.2.6"
implementation "io.ktor:ktor-client-logging-jvm:1.2.6"
implementation "io.ktor:ktor-client-serialization-jvm:1.2.6"
implementation "io.ktor:ktor-client-android:1.2.6"
implementation "com.github.aakira:napier-android:1.1.0"
}
}
iosMain {
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.14.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.2-1.3.60"
implementation "io.ktor:ktor-client-core-native:1.2.6"
implementation "io.ktor:ktor-client-json-native:1.2.6"
implementation "io.ktor:ktor-client-logging-native:1.2.6"
implementation "io.ktor:ktor-client-serialization-native:1.2.6"
implementation "io.ktor:ktor-client-ios:1.2.6"
implementation "com.github.aakira:napier-ios:1.1.0"
}
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 23 (2 by maintainers)
This issue happens on version 1.4.0 while on 1.3.2-1.4.0-rc everything works fine.
@joaquim-verges I solve it.
Worked for me with version 1.3.9-native-mt-2
Fixed with
1.3.9-native-mt-2
Try creating a new HttpClient every time you use it instead of retaining it in an instance variable. Also disable logging (remove the logging config from the client config).
I got everything working on my side with kotlin 1.4.10, ktor 1.4.0, coroutines 1.3.9-mt-2 and kotlinx.serialization 1.0.0-RC. It even works in a background thread (Dispatchers.DEFAULT). You have to take care though to create a new http client in the background thread for every call and to ensure you don’t reference other classes there that are accessed from the main thread.
See the following sample code:
I’m also facing the same issue on 1.4.0 and I thought my code was the issue or I misunderstood the variable freezing functionality. But as you all pointed out it is an issue with 1.4.0.
@e5l I understand that you have a huge load of work and that we all go to you when there is an issue especially with Ktor but we would very much appreciate any kind of update on this issue. If there is a workaround or should we revert back to 1.4.0-rc or if the issue is being worked on currently and expected to be fixed in the next version. Any kind of update would be very much appreciated.