This module contains the basic blocks to build a state machine (State and StateMachine)
- class DIRAC.Core.Utilities.StateMachine.State(level, stateMap=None, defState=None)
State class that represents a single step on a StateMachine, with all the possible transitions, the default transition and an ordering level.
>>> s0 = State(100) >>> s1 = State(0, ['StateName1', 'StateName2'], defState='StateName1') >>> s2 = State(0, ['StateName1', 'StateName2']) # this example is tricky. The transition rule says that will go to # nextState, e.g. 'StateNext'. But, it is not on the stateMap, and there # is no default defined, so it will end up going to StateNext anyway. You # must be careful while defining states and their stateMaps and defaults.
- __init__(level, stateMap=None, defState=None)
level (int) – each state is mapped to an integer, which is used to sort the states according to that integer.
stateMap (list) – it is a list (of strings) with the reachable states from this particular status. If not defined, we assume there are no restrictions.
defState (str) – default state used in case the next state is not in stateMap (not defined or simply not there).
Method that selects next state, knowing the default and the transitions map, and the proposed next state. If <nextState> is in stateMap, goes there. If not, then goes to <self.default> if any. Otherwise, goes to <nextState> anyway.
>>> s0.transitionRule('nextState') 'nextState' >>> s1.transitionRule('StateName2') 'StateName2' >>> s1.transitionRule('StateNameNotInMap') 'StateName1' >>> s2.transitionRule('StateNameNotInMap') 'StateNameNotInMap'
- class DIRAC.Core.Utilities.StateMachine.StateMachine(state=None)
StateMachine class that represents the whole state machine with all transitions.
>>> sm0 = StateMachine() >>> sm1 = StateMachine(state = 'Active')
state (None or str) – current state of the StateMachine, could be None if we do not use the StateMachine to calculate transitions. Beware, it is not checked if the state is on the states map !
Given a state name, it returns its level (integer), which defines the hierarchy.
>>> sm0.getLevelOfState('Nirvana') 100 >>> sm0.getLevelOfState('AnotherState') -1
state (str) – name of the state, it should be on <self.states> key set
int || -1 (if not in <self.states>)
Method that gets the next state, given the proposed transition to candidateState. If candidateState is not on the state map <self.states>, it is rejected. If it is not the case, we have two options: if <self.state> is None, then the next state will be <candidateState>. Otherwise, the current state is using its own transition rule to decide.
>>> sm0.getNextState(None) S_OK(None) >>> sm0.getNextState('NextState') S_OK('NextState')
candidateState (str) – name of the next state
S_OK(nextState) || S_ERROR
Returns all possible states in the state map
>>> sm0.getStates() [ 'Nirvana' ]
- setState(candidateState, noWarn=False)
- Makes sure the state is either None or known to the machine, and that it is a valid state to move into.
Final states are also checked.
>>> sm0.setState(None)['OK'] True >>> sm0.setState('Nirvana')['OK'] True >>> sm0.setState('AnotherState')['OK'] False
state (None or str) – state which will be set as current state of the StateMachine
S_OK || S_ERROR