StateMachine

StateMachine

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)

Bases: object

State class that represents a single step on a StateMachine, with all the possible transitions, the default transition and an ordering level.

Examples

>>> 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)
Parameters:
  • 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).

transitionRule(nextState)

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.

Examples

>>> s0.transitionRule('nextState')
    'nextState'
>>> s1.transitionRule('StateName2')
    'StateName2'
>>> s1.transitionRule('StateNameNotInMap')
    'StateName1'
>>> s2.transitionRule('StateNameNotInMap')
    'StateNameNotInMap'
Parameters:

nextState (str) – name of the state in the stateMap

Returns:

state name

Return type:

str

class DIRAC.Core.Utilities.StateMachine.StateMachine(state=None)

Bases: object

StateMachine class that represents the whole state machine with all transitions.

Examples

>>> sm0 = StateMachine()
>>> sm1 = StateMachine(state = 'Active')
Parameters:

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 !

__init__(state=None)

Constructor.

getLevelOfState(state)

Given a state name, it returns its level (integer), which defines the hierarchy.

>>> sm0.getLevelOfState('Nirvana')
    100
>>> sm0.getLevelOfState('AnotherState')
    -1
Parameters:

state (str) – name of the state, it should be on <self.states> key set

Returns:

int || -1 (if not in <self.states>)

getNextState(candidateState)

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.

Examples

>>> sm0.getNextState(None)
    S_OK(None)
>>> sm0.getNextState('NextState')
    S_OK('NextState')
Parameters:

candidateState (str) – name of the next state

Returns:

S_OK(nextState) || S_ERROR

getStates()

Returns all possible states in the state map

Examples

>>> sm0.getStates()
    [ 'Nirvana' ]
Returns:

list(stateNames)

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.

Examples

>>> sm0.setState(None)['OK']
    True
>>> sm0.setState('Nirvana')['OK']
    True
>>> sm0.setState('AnotherState')['OK']
    False
Parameters:

state (None or str) – state which will be set as current state of the StateMachine

Returns:

S_OK || S_ERROR