Esempio n. 1
0
    def _getState(self, machineConfig, stateConfig):
        """ Returns a State instance based on the machineConfig/stateConfig 
        
        @param machineConfig: a config._MachineConfig instance
        @param stateConfig: a config._StateConfig instance  
        @return: a State instance which is a singleton wrt. the FSM instance
        """

        if machineConfig.name in self.machines and \
           stateConfig.name in self.machines[machineConfig.name][constants.MACHINE_STATES_ATTRIBUTE]:
            return self.machines[machineConfig.name][
                constants.MACHINE_STATES_ATTRIBUTE][stateConfig.name]

        name = stateConfig.name
        entryAction = stateConfig.entry
        doAction = stateConfig.action
        exitAction = stateConfig.exit
        isInitialState = stateConfig.initial
        isFinalState = stateConfig.final
        isContinuation = stateConfig.continuation
        fanInPeriod = stateConfig.fanInPeriod

        return State(name,
                     entryAction,
                     doAction,
                     exitAction,
                     machineName=machineConfig.name,
                     isInitialState=isInitialState,
                     isFinalState=isFinalState,
                     isContinuation=isContinuation,
                     fanInPeriod=fanInPeriod)
Esempio n. 2
0
 def setUp(self):
     super(FSMContextMergeJoinTests, self).setUp()
     self.state = State('foo', None, CountExecuteCalls(), None)
     self.state2 = State('foo2', None, CountExecuteCallsWithFork(), None)
     self.state.addTransition(Transition('t1', self.state2, queueName='q'),
                              'event')
     self.context = FSMContext(self.state,
                               currentState=self.state,
                               machineName='machineName',
                               instanceName='instanceName',
                               queueName='qq',
                               obj={TASK_NAME_PARAM: 'taskName'})
     self.context.startingState = self.state
     from google.appengine.api.taskqueue.taskqueue import TaskRetryOptions
     self.context.retryOptions = TaskRetryOptions()
     self.context[INDEX_PARAM] = 1
     self.context[STEPS_PARAM] = 0
Esempio n. 3
0
 def setUp(self):
     super(ReadWriteLockTest, self).setUp()
     self.loggingDouble = getLoggingDouble()
     self.state = State('name', None, None, None)
     self.context = FSMContext(self.state, queueName='default')
     self.context.currentState = self.state
     ReadWriteLock._BUSY_WAIT_ITER_SECS = ReadWriteLock.BUSY_WAIT_ITERS
     ReadWriteLock.BUSY_WAIT_ITER_SECS = 0
     ReadWriteLock._BUSY_WAIT_ITERS = ReadWriteLock.BUSY_WAIT_ITERS
     ReadWriteLock.BUSY_WAIT_ITERS = 2
     random.seed(0)  # last step
Esempio n. 4
0
    def _init(self, currentConfig=None):
        """ Constructs a group of singleton States and Transitions from the machineConfig 
        
        @param currentConfig: a config._Configuration instance (dependency injection). if None, 
            then the factory uses config.currentConfiguration()
        """
        import logging
        logging.info("Initializing FSM factory.")

        self.config = currentConfig or config.currentConfiguration()
        self.machines = {}
        self.pseudoInits, self.pseudoFinals = {}, {}
        for machineConfig in self.config.machines.values():
            self.machines[machineConfig.name] = {
                constants.MACHINE_STATES_ATTRIBUTE: {},
                constants.MACHINE_TRANSITIONS_ATTRIBUTE: {}
            }
            machine = self.machines[machineConfig.name]

            # create a pseudo-init state for each machine that transitions to the initialState
            pseudoInit = State(FSM.PSEUDO_INIT, None, None, None)
            self.pseudoInits[machineConfig.name] = pseudoInit
            self.machines[machineConfig.name][
                constants.MACHINE_STATES_ATTRIBUTE][
                    FSM.PSEUDO_INIT] = pseudoInit

            # create a pseudo-final state for each machine that transitions from the finalState(s)
            pseudoFinal = State(FSM.PSEUDO_FINAL,
                                None,
                                None,
                                None,
                                isFinalState=True)
            self.pseudoFinals[machineConfig.name] = pseudoFinal
            self.machines[machineConfig.name][
                constants.MACHINE_STATES_ATTRIBUTE][
                    FSM.PSEUDO_FINAL] = pseudoFinal

            for stateConfig in machineConfig.states.values():
                state = self._getState(machineConfig, stateConfig)

                # add the transition from pseudo-init to initialState
                if state.isInitialState:
                    transition = Transition(
                        FSM.PSEUDO_INIT,
                        state,
                        retryOptions=self._buildRetryOptions(machineConfig),
                        queueName=machineConfig.queueName)
                    self.pseudoInits[machineConfig.name].addTransition(
                        transition, FSM.PSEUDO_INIT)

                # add the transition from finalState to pseudo-final
                if state.isFinalState:
                    transition = Transition(
                        FSM.PSEUDO_FINAL,
                        pseudoFinal,
                        retryOptions=self._buildRetryOptions(machineConfig),
                        queueName=machineConfig.queueName)
                    state.addTransition(transition, FSM.PSEUDO_FINAL)

                machine[constants.MACHINE_STATES_ATTRIBUTE][
                    stateConfig.name] = state

            for transitionConfig in machineConfig.transitions.values():
                source = machine[constants.MACHINE_STATES_ATTRIBUTE][
                    transitionConfig.fromState.name]
                transition = self._getTransition(machineConfig,
                                                 transitionConfig)
                machine[constants.MACHINE_TRANSITIONS_ATTRIBUTE][
                    transitionConfig.name] = transition
                event = transitionConfig.event
                source.addTransition(transition, event)
Esempio n. 5
0
 def test_generatedContextNameIsUnique(self):
     instanceName1 = self.context.instanceName
     state = State('foo', None, CountExecuteCalls(), None)
     context2 = FSMContext({state.name: state}, state, queueName='q')
     instanceName2 = context2.instanceName
     self.assertNotEquals(instanceName1, instanceName2)