I getting Illegal State Exception when I am invoki...
# kotlin-native
s
I getting Illegal State Exception when I am invoking higher order function from
dispatch_async_f(...)
k
I assume you're trying to pass the higher order function to another thread and you're probably not freezing it first, which you'd need to. Have more detail on the exception?
s
@kpgalligan I don't have much knowledge in Objective C. I am calling that method by passing higher order function from swift. Inside kotlin file, I am using dispatch_async_f() and after that I am calling that block. How would I fix this ?
s
@olonho I have used the same
executeAsync
but the thing is I need to invoke higher order function after result
o
there shall be no difference, if you pass the context - it shall be executable, and there’s not much difference which order function is
s
@olonho @kpgalligan I am getting this kind of exception
Copy code
Uncaught Kotlin exception: kotlin.IllegalStateException: Illegal transfer state
        at 0   common                              0x0000000103b16a76 kfun:kotlin.Exception.<init>(kotlin.String?)kotlin.Exception + 70
        at 1   common                              0x0000000103b16996 kfun:kotlin.RuntimeException.<init>(kotlin.String?)kotlin.RuntimeException + 70
        at 2   common                              0x0000000103b23246 kfun:kotlin.IllegalStateException.<init>(kotlin.String?)kotlin.IllegalStateException + 70
        at 3   common                              0x0000000103b475e2 ThrowWorkerInvalidState + 66
        at 4   common                              0x0000000103b66f0d Kotlin_Worker_detachObjectGraphInternal + 93
        at 5   common                              0x0000000103b48233 kfun:kotlin.native.concurrent.DetachedObjectGraph.<init>(kotlin.native.concurrent.TransferMode;kotlin.Function0<#GENERIC>)kotlin.native.concurrent.DetachedObjectGraph<#GENERIC> + 83
        at 6   common                              0x0000000103b4833a kfun:kotlin.native.concurrent.DetachedObjectGraph.<init>(kotlin.native.concurrent.TransferMode;kotlin.Function0<#GENERIC>;kotlin.Int;kotlin.native.internal.DefaultConstructorMarker)kotlin.native.concurrent.DetachedObjectGraph<#GENERIC> + 186
o
it means you’re trying to detach smth still referred and not frozen
k
To take a conceptual step back, threading in native is different than what you're probably used to. In summary, state can either be accessed by one thread at a time, or frozen and accessed by multiple. If you're not going to freeze it, you can pass it to another thread. To do that, you need to detach it from the rest of the object graph (which is why you're using DetachedObjectGraph). If you try to do that but the state is being pointed to externally, it won't work. In general I prefer freezing state because it's simpler to manage.
Seeing the code calling this would probably help
s
@kpgalligan here is the code
Copy code
executeAsync(NSOperationQueue.mainQueue) {
            val response = task.response as? NSHTTPURLResponse
            Pair(when {
                response == null -> QueryResult(null, didCompleteWithError?.localizedDescription)
                response.statusCode.toInt() != 200 -> QueryResult(null, "${response.statusCode.toInt()})")
                else -> QueryResult(
                    NSJSONSerialization.JSONObjectWithData(receivedData, 0, null) as? Map<String, *>,
                    null
                )
            }, { result: QueryResult ->
                    block.invoke(result)
            })
        }
    }
}

inline fun <reified T> executeAsync(queue: NSOperationQueue, crossinline producerConsumer: () -> Pair<T, (T) -> Unit>) {
    dispatch_async_f(queue.underlyingQueue, DetachedObjectGraph {
        producerConsumer()
    }.asCPointer(), staticCFunction { it ->
        val result = DetachedObjectGraph<Pair<T, (T) -> Unit>>(it).attach()
        result.second(result.first)
    })
}
k
Well, unrelated, I assume you're getting json from a network call. You could try using ktor. Alternatively, we're doing exactly this in the droidcon app using roughly similar techniques you're trying to use: https://github.com/touchlab/DroidconKotlin/blob/master/sessionize/lib/src/iosMain/kotlin/co/touchlab/sessionize/platform/Functions.kt#L41
👌 1
K 1
👍 1
My guess is you're having trouble with 'block'. I don't see where that's coming from. If its from outside of that code, then it's almost certainly complaining about that.
s
@kpgalligan block is a field in that class. It is actually passed from swift
@kpgalligan Thanks for your time. I have called
feeze()
for return of data
Copy code
inline fun <reified T> executeAsync(queue: NSOperationQueue, crossinline producerConsumer: () -> Pair<T, (T) -> Unit>) {
    dispatch_async_f(queue.underlyingQueue, DetachedObjectGraph {
       // added freeze() here
        producerConsumer().freeze()
    }.asCPointer(), staticCFunction { it ->
        val result = DetachedObjectGraph<Pair<T, (T) -> Unit>>(it).attach()
        result.second(result.first)
    })
}
This has solved all the problems @kpgalligan Can you help me with any document which describes about
freeze()
so that I could understand it well.
k
Was just trying to make a list...
Nikolay's video is there
I try to give an overview in this talk at Droidcon London: https://skillsmatter.com/skillscasts/12710-kotlin-multiplatform-architecture
(you need to make an account, but the video is free)
I'm super overdue for writing another blog post about it. I keep starting and getting side tracked.
A tiny bit here. I made a collections library that works with atomics: https://medium.com/@kpgalligan/stately-a-kotlin-multiplatform-library-b72112164b3e
Assuming I write a blog post about state in the future I'll post that here. The first one I did is super old now: https://medium.com/@kpgalligan/kotlin-native-stranger-threads-c0cf0e0fb847
s
@kpgalligan Thanks for your comments. I am actually trying to develop small app which uses kotlin native multiplatform. I will post if I face any issues during the course of development 👍 Hope you will write that blog in this year itself. Please don't forget to dm me if you complete that blog..
k
"Production" app or something you're testing out? I'm giving a talk in 2 weeks about kotlin multiplatform in production
s
It's not a production one 😀 Just testing the abilities of multiplatform