22. Persisting State Machine

Traditionally an instance of a state machine is used as is within a running program. More dynamic behaviour is possible to achieve via dynamic builders and factories which allows state machine instantiation on-demand. Building an instance of a state machine is relatively heavy operation so if there is a need to i.e. handle arbitrary state change in a database using a state machine we need to find a better and faster way to do it.

Persist feature allows user to save a state of a state machine itself into an external repository and later reset a state machine based of serialized state. For example if you have a database table keeping orders it would be way too expensive to update order state via a state machine if a new instance would need to be build for every change. Persist feature allows you to reset a state machine state without instantiating a new state machine instance.

[Note]Note

There is one recipe Chapter 25, Persist and one sample Chapter 32, Persist which provides more info about persisting states.

While it is possible to build a custom persistence feature using a StateMachineListener it has one conceptual problem. When listener notifies a change of state, state change has already happened. If a custom persistent method within a listener fails to update serialized state in an external repository, state in a state machine and state in an external repository are then in inconsistent state.

State machine interceptor can be used instead of where attempt to save serialized state into an external storage is done during the a state change within a state machine. If this interceptor callback fails, state change attempt will be halted and instead of ending into an inconsistent state, user can then handle this error manually. Using the interceptors are discussed in Chapter 20, State Machine Interceptor.