Ktor-client inside CoroutineWorker.execute - Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
See original GitHub issueI just watched the talk that @benasher44 gave at droidCon NYC about Concurrency in Kotlin/Native and decided to try this CoroutineWorker
library.
So what I am trying to do is consuming some backend REST API using Ktor inside CoroutineWorker.execute
. Basically, I am still not really sure if I am doing this correct but here is the code:
So I have a NetworkProvider
class:
internal class NetworkProvider<T : Endpoint>(private val engine: HttpClientEngine) {
private val client: HttpClient by lazy {
HttpClient(engine) {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
}
}
@UnstableDefault
internal suspend fun <R> request(endpoint: T, strategy: DeserializationStrategy<R>): R {
val response: String = client.request {
method = endpoint.method
url.apply {
protocol = URLProtocol.HTTPS
host = endpoint.baseUrl
val query = endpoint.parameters
.map { "${it.key}=${it.value}" }
.joinToString("&")
encodedPath = if (query.isNotEmpty()) {
"${endpoint.path}?$query"
} else {
endpoint.path
}
}
}
return Json.nonstrict.parse(strategy, response)
}
}
And then I use this NetworkProvider
inside my Repository class like this:
internal class MovieRepositoryImpl(
private val provider: NetworkProvider<MovieEndpoint>
) : MovieRepository {
override fun getMovieList(
year: Int,
page: Int,
sort: String,
completion: (Result<MovieListEntity>) -> Unit
) {
CoroutineWorker.execute {
val result = try {
val response = provider.request(
endpoint = MovieListEndpoint(year, page, sort),
strategy = MovieListEntity.serializer()
)
Result.Success(response)
} catch (error: Throwable) {
Result.Failure(error)
}
CoroutineWorker.withContext(MainDispatcher) {
completion(result)
}
}
}
}
But it’s end up gave me this error messages:
Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread
at 0 MovieCore 0x0000000109964fe7 kfun:kotlin.Throwable.<init>(kotlin.String?)kotlin.Throwable + 87
at 1 MovieCore 0x000000010995e355 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 85
at 2 MovieCore 0x000000010995df15 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 85
at 3 MovieCore 0x0000000109990c95 kfun:kotlin.native.IncorrectDereferenceException.<init>(kotlin.String)kotlin.native.IncorrectDereferenceException + 85
at 4 MovieCore 0x00000001099add29 ThrowIncorrectDereferenceException + 137
at 5 MovieCore 0x0000000109cd3799 CheckIsMainThread + 25
at 6 MovieCore 0x0000000109c5a893 kfun:utils.<get-MainDispatcher>$core()kotlinx.coroutines.CoroutineDispatcher + 35
at 7 MovieCore 0x0000000109c3f7e4 kfun:repository.MovieRepositoryImpl.$getMovieList$lambda-1COROUTINE$1.invokeSuspend#internal + 1892
at 8 MovieCore 0x0000000109c40020 kfun:repository.MovieRepositoryImpl.$getMovieList$lambda-1COROUTINE$1.invoke#internal + 256
at 9 MovieCore 0x0000000109b069f3 kfun:kotlinx.coroutines.intrinsics.startUndispatchedOrReturn$kotlinx-coroutines-core@kotlinx.coroutines.internal.ScopeCoroutine<#GENERIC>.(#GENERIC;kotlin.coroutines.SuspendFunction1<#GENERIC,#GENERIC>)Generic + 899
at 10 MovieCore 0x0000000109ab11bd kfun:kotlinx.coroutines.coroutineScope(kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 429
at 11 MovieCore 0x0000000109c37f70 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-1COROUTINE$11.invokeSuspend#internal + 1520
at 12 MovieCore 0x0000000109c386a0 kfun:com.autodesk.coroutineworker.CoroutineWorker.Companion.WorkItem.$<init>$lambda-1COROUTINE$11.invoke#internal + 256
at 13 MovieCore 0x0000000109c33226 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$processWorkItems$lambda-0COROUTINE$7.invokeSuspend#internal + 726
at 14 MovieCore 0x0000000109986618 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) + 712
at 15 MovieCore 0x0000000109afb06c kfun:kotlinx.coroutines.DispatchedTask.run() + 2732
at 16 MovieCore 0x0000000109ab606d kfun:kotlinx.coroutines.EventLoopImplBase.processNextEvent()ValueType + 813
at 17 MovieCore 0x0000000109b097c6 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 1958
at 18 MovieCore 0x0000000109b0886e kfun:kotlinx.coroutines.runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>)Generic + 1246
at 19 MovieCore 0x0000000109b08de4 kfun:kotlinx.coroutines.runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,#GENERIC>;kotlin.Int)Generic + 372
at 20 MovieCore 0x0000000109c32da9 kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.enqueueWork$<anonymous>_3#internal + 217
at 21 MovieCore 0x0000000109c340fb kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$<anonymous>_3$FUNCTION_REFERENCE$7.invoke#internal + 59
at 22 MovieCore 0x0000000109c3415b kfun:com.autodesk.coroutineworker.BackgroundCoroutineWorkQueueExecutor.$enqueueWork$<anonymous>_3$FUNCTION_REFERENCE$7.$<bridge-UNN>invoke()#internal + 59
at 23 MovieCore 0x0000000109c3cca4 kfun:com.autodesk.coroutineworker.WorkerPool.performWork$lambda-1#internal + 308
at 24 MovieCore 0x0000000109c3d0df kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$17.invoke#internal + 63
at 25 MovieCore 0x0000000109c3d13b kfun:com.autodesk.coroutineworker.WorkerPool.$performWork$lambda-1$FUNCTION_REFERENCE$17.$<bridge-UNN>invoke()#internal + 59
at 26 MovieCore 0x00000001099927c1 WorkerLaunchpad + 177
at 27 MovieCore 0x0000000109cd8069 _ZN6Worker19processQueueElementEb + 2569
at 28 MovieCore 0x0000000109cd8616 _ZN12_GLOBAL__N_113workerRoutineEPv + 54
at 29 libsystem_pthread.dylib 0x00007fff51c04d36 _pthread_start + 125
Anyone know how to work around this error message?
Issue Analytics
- State:
- Created 4 years ago
- Comments:14
Top Results From Across the Web
IncorrectDereferenceException when trying to ... - YouTrack
Uncaught Kotlin exception : kotlin.native.IncorrectDereferenceException: Trying to access top level value not marked as @ThreadLocal or ...
Read more >Multithreading in Kotlin Multiplatform Apps - helw.net
As a review, the rules are that an object is either: immutable (and therefore can be shared across multiple threads), or; mutable (and...
Read more >Kotlin/Native iOS. 3. Coroutines and Immutability of K/N
This chapter's topic is to use coroutines in K/N and its current status. ... what thread the corresponding coroutine uses for its execution....
Read more >Kotlin Multiplatform: IllegalStateException: Must be main thread
Koin on Kotlin/Native requires injection on the main thread, to avoid freezing Koin state. As a result, you can't actually inject directly ...
Read more >WhatsNew 1.4 | Ktor Framework
ResponseException is no longer serializable starting from 1.4.0 (breaking change) ... ktor-client-apache: thread stuck in ByteBufferChannel.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Since there’s no follow up to do with CoroutineWorker, I’m going to close this. Hopefully this helped understand a bit more what’s going on, and further discussion / resolution should probably be redirect to the ktor and Kotlin-native channels in Kotlin slack.
Thanks for using CoroutineWorker! If you disagree with my assessment, feel free to reopen
No problem sounds good! Best of luck 😃