Search code examples
kotlinconcurrencykotlin-coroutineskotlin-multiplatformkotlin-native

Initializing IsolatedState results in IllegalStateException


I am trying to use IsolatedState from Stately in my project. E.g. I have a view model, containing some data structure to display. It is initialized with that data structure instance and then I'm trying to create an IsolatedState to be able to apply user actions and bg actions to mutate the same instance from different threads.

class ViewModel() {

    constructor(data: SomeData) : this() {
        println("Hey: ${data.isFrozen}")
        println(1)
        isolatedData = IsolateState { data }
        println(2)
    }

    lateinit private var isolatedData: IsolateState<SomeData>

}

The output is

Hey: false
1

And then the exception kotlin.IllegalStateException: Mutable state shouldn't be frozen is raised. So it seems that data is not frozen before initializing IsolatedState. Is something wrong in the way I am initializing it?


Solution

  • Is something wrong in the way I am initializing it?

    Yes. The constructor for IsolateState takes a producer lambda. That lambda should return some data that is mutable (ie. not frozen). The lambda itself runs in a different thread that is controlled by the runtime that manages IsolateState. That lambda needs to be frozen to be run on that thread, which freezes data.

    For this to work, it would need to look something more like the following:

        constructor(id: Int) : this() {
            isolatedData = IsolateState { SomeData(id) }
        }
    

    The lambda basically needs to create the mutable class instance. You can't pass mutable data into an instance of IsolateState. The producer lambda needs to create it.