Closed asomov closed 7 months ago
Hi, the short answer - yes, it can be called from any context (thread).
Details: If you are using StateMachine instance created by createStateMachine/createStateMachineBlocking functions (with CoroutineScope specified), then it is safe to call any suspendable library methods (including processEvent()) on such instance, from any CoroutineContext (driven by any thread), as all those methods switch the CoroutineContext internally to machines one.
But if you create StateMachine instance without coroutines support (by createStdLibStateMachine) then the answer is no, as internal context switching cannot be performed in such case.
See Coroutines section in docs, there was some explanation regarding this behaviour.
Please don't forget that the CoroutineScope that you specify when creating a StateMachine instance sould be driven by single thread. That is actually preserves the guaranties that you have mentioned in coroutines environment.
Thank you the the quick and descriptive answer ! I think it deserves to be in the docs instead of a very short and confusing statement.
I have updated the docs, and linked related sections.
@nsk90 may I ask you to add yet another sample to the ones provided inside the project with the way to properly create the Scope ? Please don't forget that the CoroutineScope that you specify when creating a StateMachine instance sould be driven by single thread.
Or the one shown in the docs is the way ? (is the machineScope
single threaded there ?)
CoroutineScope(newSingleThreadContext("context"))
CoroutineScope(Dispatchers.Main)
here are some samples, I will attach them to the docs.
(is the machineScope single threaded there ?)
yes it is also single threaded, runBlocking
implementation creates an event loop on current running thread (it will be used as context thread), if the context is not specified explicitly.
The documentation clearly states: KStateMachine is designed to work in single thread. Concurrent modification of library classes will lead to race conditions.
Does is also mean that the calls to
processEvent()
must be done from the same thread ? I understand that creating the state machine with its states, listeners and transitions is single-threaded. But may beprocessEvent()
can be called from different threads ?