views:

153

answers:

1

The scenario:
I have a simple state machine:

Happy path:

Uninitialized->Initialized->InProgress->Done

Unhappy path:

Uninitialized->Initialized->Error

Simply put, I need to cause a transition (either into InProgress or in Error state) without an external event/trigger. I.e. Initialized state should immediately result in one of those states.

Questions:

  1. Is it OK to cause state transition from within Initialized.Enter() ?
  2. I could use state guards to do this, but I'd rather not have non-trivial logic in the state guard (and initialization can very well be complex).
  3. If it is NOT OK, how can I do it differently?
  4. Should I just take this decision out of he FSM all together and have some other component cause the appropriate transition? But then, wouldn't I still have to call that external component from within Initialized.Enter() ? so it solves nothing?
+2  A: 

In a state machine, next state is a combinatorial logic function of both input and current state.

In the case you are describing, the same cause (Initialized state) seems to be able to trigger two different effects (either InProgress or Error state). I guess that there is a hidden input whose value makes the difference. I also guess that this input is received during transition from Uninitialized to Initialized.

Therefore I would have a different model:

Uninitialized -> Successfully initialized -> InProgress -> Done
             \
              `-> Failed Initialization -> Error

Possibly combining Successfully initialized with InProgress and Failed initialization with Error.


EDIT: From your comment, I understand that the hidden input actually is the result of an action (a device initialization). Taking your model, I assume that initialization takes place while in Initialized state (let's call it Initializing). This way, the result from the device is your external event which will trigger transition either to InProgress or to Error.

So keep your state machine and simply add the result of device.Initialize() to the list of inputs or external events.

mouviciel