Closed estambakio-sc closed 5 years ago
Basic functionality is done. Now it's time to hook Machine.canRelease
to Machine's sendEvent
, availableTransitions
, can
. This requires some discussion @asergeev-sc
According to previous discussions, canRelease
should be checked before checking for available transitions. If state cannot release, there's no sense in checking available transitions.
But ability to specify to
state in states['mystate'].release introduces complexity. Let me explain.
If to
is undefined - this array of guards should be checked both for canRelease({ object })
(without specified target state) and canRelease({ object, to: 'some_target_state' })
.
If to: 'some_target_state'
is defined (string or array of strings) then this array of guards should be checked for canRelease({ object, to: 'some_target_state' })
only, but not for different values or undefined one.
Now to the point.
If we check release
guards before findAvailableTransitions
then we have information only about object
, and we can check only those release
guards which have to === undefined
. Information about to
state is available only when we have a list of transitions from that state.
Therefore workflow will look like this:
to === undefined
guards)to
stateto === undefined
and to === transition.to
because undefined
value means this guard should be checked no matter what)We end up checking to === undefined
guards twice. << main concern
Guards can be asynchronous functions, and therefore duplicate calls will create additional unneeded latency if a guard makes HTTP request for example.
I see two options:
release
guards only after checking transitions? But it means we check transition-related guards before checking if object can leave that state, which looks not optimal. Why check transitions if we can't even leave the state?to === undefined
guards), then find available transition, and then check again if object can be released to foundTransition.to
state (which involves checking to === undefined
guards again as a part of process).The first option is ok.
Machine.availableTransitions is not related to 'release' guards, so it does not need to be touched. Only can and sendEvent needs to be updated with additional release guards checks.
Logically sendEvent could look like this: loop via all schema transitions where from, to, event correspond to passed parameters; for each found transition, check if the object can be released "from" state in "to" the one found, if yes, then transition specific guards too and if all guards are resolved into true then transition happens. Similar logic could be applied in 'can'.
for each found transition, check if the object can be released "from" state in "to" the one found
My considerations regarding this line:
sendEvent
takes into account the first found transition only; therefore only this single transition should be checked against canBeReleased
functioncan
on the contrary doesn't limit transitions to a single one; therefore canBeReleased
will be checked against all found transitions.
90