Is there a way in which I can define global transitions/actions on a Spring state machine?
The expectation is, I'll not be transitioning to any other state. But just accept the event and perform the action and stay in the current state.
Turned out that there is no support for global transition. We developed a layer on top of Spring State Machine(SSM), which could be configured with JSON. From that, we had a possibility to define the global transition. And, when translating to SSM objects, the global transition will be added to all the states.
Related
How does Spring Statemachine handle two transitions that has the same source state?
For example:
Source State: ready
Event: start
One transition will be lead to the target state running, another one will be failure
Any help would be appreciated.
the scenario you described above can be achieved in two ways.
In case of failure to process the incoming event (START), machine would remain in the original state (ready). The transition is only completed when event is process successfully.
However, if you really need to get away from READY state and move to RUNNING or FAILURE, one can use the Guard condition. You can use an evaluation function to define if the START event was successful or not and define to which state machine should go to.
This can be achieved using a CHOICE pseudo-state that is protected by a Guard class, based on machine configuration and Guard evaluation, machine would move to the expected state
The official doc for reference on how to make the implementation is here
love the elsa-workflows project as I was heavily using WWF in the past. However many of my workflows where state machines. I can't see any in elsa, any plans to support this ?
Elsa 2 does not support the state machine model (only the flowchart model), but I am planning on revising the engine for Elsa 3 which would allow any type of model, including state machine and simple sequential flows like we have in Windows WF.
UPDATE
After I answered with the above I started to think ahead of the state machine architecture for V3, during which I realized we can implement the state machine model already today with V2.
All it would take is a simple new activity called e.g. "State" that has an infinite number of outcomes. This State activity would simply set a workflow variable called e.g. "StateMachineState" or "CurrentState". Each outbound connection would be connected to any trigger responsible for transitioning into the next state. This could be a message from a service bus, a timer, an HTTP request, or anything else that's available with Elsa.
The only real change that would need to be added to make the user experience smooth is the ability to keep adding connections without having to specify them manually from the activity editor. With the current design, we could probably just automatically add an extra outcome to the activity. So initially there would just be e.g. "Transition 1". When that one becomes connected, a "Transition 2" would appear.
Anyway, I am revising my answer to: it's not here yet, but:
You can implement it yourself today, and
I will add an initial version of the State machine model to either Elsa 2.1 or 2.2, depending on any hidden gotchas I might have failed to see.
UPDATE 2
I just pushed a change that includes a State activity.
With this, you can now easily implement a state machine by adding State activities to your workflow. Here's an example of a traffic light state machine:
This workflow kick starts automatically after 5 seconds, after which it will transition into the "Green" state. Then it stays there for 10 seconds before transitioning into the "Yellow" state. After 5 seconds, it then transitions into the "Red" state, and finally transitions back to the "Green" state after 5 seconds. Then it repeats.
To use the State activity, you specify things:
State name.
Allowed transitions (the traffic light example includes only one transition per state, but you can specify more than just one).
I am making mulitplayer quiz like game. I have chosen to use spring state machines to model each individual instance of the game on the server using #EnableStateMachineFactory. But, I need every instance of the state machine to have additional game data/state info, and to init that data on the state machine startup with some custom startup data (like player usernames for example). Is ExtendedState intended for such stuff and if it is how to send custom initial extended state data when creating the state machine with factory?
Yes ExtendedState is only way to store data within a machine itself. I've used it like that so it's ok.
Order to initialize ExtendedState I'd use machine's initial action which is executed when initial state entry logic happens. In UML machine model it's purpose by definition is to init machine.
Initial State
My idea is to keep track of states of a domain object by spring statemachine. i.e. statemachine defines how to transit states of the domain object. When the events are persisted/restored to/from the event store, the state of the domain object can be (re)generated by sending events to the statemachine.
However, it seems that creating a statemachine object is relatively expensive, it's not that performant to create a state-machine object whenever a state transition happened on a domain object. If I only maintain a statemachine object, I would worry about concurrency problems. One approach is to have a 'statemachine-pool', but it gets messy if I have to create statamachines for multiple different domain objects.
So is it a good idea to apply spring statemachine with event sourcing pattern?
Provided that all the transitions are based on events I would say that it is a pretty good idea, yes.
The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.
The main point about event sourcing is that you store the events leading to a particular state - instead of just storing the current state - so that you can replay them up to a given point of time.
Thus, using event sourcing has no impact on how you create your state machines.
However, it seems that creating a state-machine object is relatively expensive, it's not that performant to create a state-machine object whenever a state transition happened on a domain object.
Creating a state-machine every time there is a state transition is not related with event sourcing. Would you do it differently if you were only storing the current state? You'd still need to either create the state-machine from the last stored state - or look it up in a cache or a pool - before you could apply the transition.
The only performance hit derived from using event sourcing would be that of replaying the transitions from the beginning in order to reach the current state. Now, if this is costly you can use snapshots to minimize the amount of transitions that must be replayed.
I have a program with a lot of controllers which need to co - ordinate with each other . I'm confused about which mechanism to use . What are the pro and con of using :
Delegate
Bindings
Notifications
Key Value observing
Specifically is there any problem with using notifications all over place ? I'm planning to do that as it allows a class to just put out some information and not bother about anything else.
Use delegates if you want your object to have knowledge of specific methods to call when it needs to inform an observer of a state change. Notifications are more appropriate when you have multiple observers. Both of these require manual intervention, i.e. you need to explicitly call the delegate methods or post notifications when state changes.
Bindings and KVO work hand-in-hand, and are automatic ways to update state in one object (e.g. UI) when state in another object changes.