-
Notifications
You must be signed in to change notification settings - Fork 310
Non-deterministic FSM? #129
Comments
The main question here, is how to express the non-determinism in a declarative way? It would be nice to keep ability to draw state diagrams. I thought about something like this:
in case of RESULT_STATE as the target, the return value of a function should be one of the listed states. The bad thing here, that the library capture a return value of the transition for own usage. But may be it's not a big issue for the end users. |
That’s exactly I’m looking for right now. My use case would be to get to different error states based on the exceptions thrown. I was thinking about using error=(((ExceptionClass1,ExceptionClass2,), 'state'), ((ExceptionClass3, ExceptionClass4), 'other-state')), although it looks strange now that I typed it :) |
After some thinking and code writing I'm no longer sure it's a good idea to put nondeterminism into Right now I'm solving the problem like this: @transition(field=payment_state,
source=[PAYMENT_STATES.upcoming,
PAYMENT_STATES.delinquent],
target=PAYMENT_STATES.charged)
def _mark_as_charged(self):
pass
@transition(field=payment_state,
source=[PAYMENT_STATES.upcoming,
PAYMENT_STATES.delinquent],
target=PAYMENT_STATES.delinquent)
def _mark_as_delinquent(self):
pass
def can_charge(self):
return (fsm_can_proceed(self._mark_as_charged) and
fsm_can_proceed(self._mark_as_delinquent))
def charge(self):
if not self.can_charge():
raise TransitionNotAllowed(("can't charge when in state '{}'".
format(self.payment_state)))
charge_succeeded = StripeCharge.perform_charge(self)
if charge_succeeded:
self._mark_as_charged()
else:
self._mark_as_delinquent()
self.save() It's not pretty, but makes some sense IMO. However, I'm not sure it's possible to get away without first-class "signals" or something similar to what you did in Workflow. |
Do you think it's reasonable or possible to allow non-deterministic FSMs in django-fsm? An example would be a following machine representing some charge with three states:
Depending on an external factors (success of charge), "make_charge" signal/transition can lead either to "successful" or to "declined" state. However, this is true only assuming that "transition" is meant to be somewhat equivalent to a "signal" in a classic FSM parlance. If it's not the case, it's reasonable to emulate classic FSMs on top of django-fsm, but it will require quite a lot of boilerplate.
The text was updated successfully, but these errors were encountered: