Stately
Stately copied to clipboard
Nested iso collections cannot be created from the state runner thread (causes deadlock)
We have a bit of fairly complicated logic in our project that uses an IsoMutableMap
whose value is another IsoMutableMap
, something like
val nested = IsoMutableMap<Int, IsoMutableMap<Int, Int>>()
As part of a recent change, we ended up with some code that boils down to
nested.access {
it[0] = IsoMutableMap()
}
and were surprised to find that this causes a deadlock:
-
IsoMutableMap
constructor callscreateState
- That function isn't aware of the
StateHolder
so it just directly callsrunner.stateRun
, not realizing we're already on the thread it wants to run on - Work gets enqueued to run on the current thread later
- Current thread blocks on that future work - deadlock
Not sure if there's a clean way that the threading information could be conveyed here to do the right thing.
You might be able to work around by manually passing separate StateRunner
s
I'd need to think about this. We have some internal constructors that let you fork off state. Not on IsoMutableMap
, though. You may be able to try something like this:
fun <K, V> IsoMutableMap<K, V>.makeMap(): IsolateState<MutableMap<K, V>> = access { IsolateState(fork(mutableMapOf<K, V>())) }
Then your type would be
val nested = IsoMutableMap<Int, IsolateState<MutableMap<K, V>>>()
There's probably a better way to handle it, but I haven't done a ton of iso state in a while