What does it mean by db update not guaranteed of AASM hook? - ruby

I'm reading AASM docs and trying to decide which hook I'm going to use.
On their docs: https://github.com/aasm/aasm#extending-aasm
What does it mean by # if persist successful, database update not guaranteed here?
Can anyone explain the differences between before_success and success hooks?
Do I have to call .save if I'm modifying an attribute of the same ActiveRecord object on these hooks?
Thanks

Let's assume you have an event run defined on your model that changes the state from stop to running like this.
aasm do
state :stop, initial: true
state :running
event :run do
transitions from: :stop, to: :running
end
end
Then calling instance.run would try to change the state to running which would fail if the instance is already in running state. If successful, the state would have been changed on the instance in memory, but would not be saved into the database.
Whereas instance.run! would do the same, but would additionally try to save the changed state into the database. Saving the new state into the database could still fail. For example, when there is a validation failing on the record after the state change or because you updated other attributes on the instance at the same time.
That said: Those callbacks are fired based on the state machine logic, not on the underlying database logic. For example, transition success only means that the state changed successfully on the instance in memory, not necessarily in the database too. When you want to fire a callback after the database update, then use a ActiveRecord after_commit callback instead.

Related

Spring Statemachine: how to handle two transitions that has the same source state?

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

Do I need to store last state of object in separate table in Event Sourcing

I'm still learning event sourcing i dont undestand something.
When i get a command to change object, do I first recreate that object from event store than change it and save event, or should i have separate table that holds last state?
What is practice here?
I'm still learning event sourcing i don't understand something. When i get a command to change object, do I first recreate that object from event store than change it and save event, or should i have separate table that holds last state? What is practice here?
The first rule of optimization: Don't.
For handling commands, all of the information that you need to have is stored in your event history; simply loading the history and recomputing any state you need will get the job done.
In the case where you need low latency in your command handler, AND recomputing the state you need from the event history is too slow to meet your service level targets, then you might look into saving a "snapshot", and using that to speed up the load of your data.
Current consensus is that snapshots should be saved separately from the event history (ie: a snapshot is not another kind of event), as though the snapshot were another "read model".

How to check if the event triggers the state machine in Spring Statemachine?

Let me summarize my question as follows,
I know that the stateMachine.sendEvent(Event e) returns a boolean value representing if the event triggers a transition or not, but it also triggers the transition if true.
However, I want only to check if the state machine is triggerable by that event or not, and not to trigger the transition afterwards. Is there any way to do that?
There is no built-in method to do that, but once you retrieve an instance of a StateMachine, you can implement a method to iterate over the transitions looking for the current state and check what are the available transitions for that state. Each AbstractTransition contains a source and target state
machine.getTransitions()

What is the difference between a state action and an entry action and what is the Papyrus counterpart of a state action

I am playing around with the Spring state machine project and Eclipse Papyrus respectively.
I have two questions about actions:
What is the difference between a so-called state action and an entry action of a State?
What is the counterpart of a state action in Papyrus? The documentation describes only entry and exit actions.
Thanks a lot.
Can't tell about Papyrus, but you can specify tree different actions for state. You can use following methods to avoid confusion:
stateEntry - executed when entering the state.
stateDo - also referred as state's action. Executed when entered the state, technically is executed after entry action.
stateExit - executed prior to leaving the sate.
The long story short, state action is executed before entry action. If you need only one action for the state you can choose either.

State machine: validation before initial save in database?

This is a question regarding state machines in general, I don't need help with the actual implementation. Imagine a state machine that formalizes a simple bug report, from inception to its final demise. The bug might transition across states such as "NEW", "CONFIRMED", "RESOLVED", "REOPENED", and "CLOSED". Along with every state transition there is also some accompanying validation code, which could for instance make sure that when moving from NEW to CONFIRMED we have recorded who confirmed it.
My question is related to the initial state – when the bug is just "NEW". It's tempting to say that initial validation is not part of the state machine (e.g. making sure that the bug actually has some description, for instance, before saving it with state "NEW" in the database). But isn't that also a state transition, from "just created" to "NEW"? Shouldn't that transition be validated like any other transition? Isn't it artificial and sub-optimal to separate the initial validation from all other validations?
On the other hand, if we do create a "fake" initial state (say, "CREATED"), along with its respective transition ("CREATED" --> "NEW"), then what happens when that transition isn't validated? If it is validated, it's all good – we switch states and we save the object with the new state (actually called "NEW" here) in the database. But if it doesn't validate then we obviously don't want to save it in the database, and that breaks the state machine pattern by not having an initial state and a final state (we would have an initial state, albeit a fake one – "CREATED" –, but two final states – "CLOSED" and "DELETED"). Not only that, but the "DELETED" state would also be fake, in that there will never be any persistent objects with that state (just as there will never be any persistent objects with state "CREATED").
How do you handle this issue?
Ok, after further investigation it looks like the pattern does solve my issue by itself: in some (most?) state machine models, there is in fact an initial transaction that ends in the initial state. So there is in fact a "fake" initial state, as far as the actual code is concerned, but that state must not be considered a real state in the state machine.

Resources