Redux on Multi-threaded Platforms
In a multi-threaded system invalid states and race conditions can happen.
For example if
getState was called at the same time as a dispatch, the state could represent a past
state. Or 2 actions dispatched concurrently could cause an invalid state.
So you there are 3 options:
- Synchronize access to the store - createThreadSafeStore()
- Only access the store from the same thread - createSameThreadEnforcedStore()
- Live in the wild west and access store anytime, any thread and live with consequences - NOT_RECOMMENDED - createStore()
ReduxKotlin allows all these, but most cases will fall into #1.
Starting with ReduxKotlin 0.5.0 there is a threadsafe store which uses synchronization (AtomicFu library) to allow safe access to all the functions on the store. This is the recommended usage for 90% of use cases.
val store = createThreadSafeStore(reducer, state)
createStore is the way to go. Other possible reasons could be applications that need optimal
performance, however it is unlikely that the extra overhead from synchronization will be an issue.
Same thread enforcement
Another option is
same thread enforcement. This means these methods must be called from the same thread where
the store was created. An
IllegalStateException will be thrown if one of these are called from a
Same thread enforcement was the default behavior for ReduxKotlin 0.3.0 - 0.4.0.
Note that this is SAME thread enforcement - not MAIN thread enforcement. ReduxKotlin does not force you to use the main thread, although you can if you'd like. Most mobile applications do redux on the main thread, however it could be moved to a background thread. Using a background thread could be desirable if the reducers & middleware processing produce UI effects such as dropped frames.
same thread enforcement is implemented for JVM, iOS, & macOS. The other platforms
have do not have the enforcement in place yet.
same thread enforcement:
val store = createSameThreadEnforcedStore(reducer, state)
Wild west - no enforcement
createStore() may be used if the project is only a single threaded application (i.e. JS only), or you
just want control access within your codebase(NOT_RECOMMENDED).
IF you are using vanilla
createStore(), then you may use an different artifact,
and avoid pulling in AtomicFu dependency:
ONLY USE THE ABOVE IF YOU DO NOT WANT THREAD SAFETY