Exemple #1
0
 def _check(self, name, check_compiled, check_storage_ensured):
     """Check (and raise) if the engine has not reached a certain stage."""
     if check_compiled and not self._compiled:
         raise exc.InvalidState("Can not %s an engine which"
                                " has not been compiled" % name)
     if check_storage_ensured and not self._storage_ensured:
         raise exc.InvalidState("Can not %s an engine"
                                " which has not has its storage"
                                " populated" % name)
Exemple #2
0
 def wrapper(self, *args, **kwargs):
     if check_compiled and not self._compiled:
         raise exc.InvalidState("Can not %s an engine which"
                                " has not been compiled" % do_what)
     if check_storage_ensured and not self._storage_ensured:
         raise exc.InvalidState("Can not %s an engine"
                                " which has not had its storage"
                                " populated" % do_what)
     if check_validated and not self._validated:
         raise exc.InvalidState("Can not %s an engine which"
                                " has not been validated" % do_what)
     return meth(self, *args, **kwargs)
Exemple #3
0
    def process_event(self, event):
        """Trigger a state change in response to the provided event.

        :param event: event to be processed to cause a potential transition
        """
        current = self._current
        if current is None:
            raise NotInitialized("Can only process events after"
                                 " being initialized (not before)")
        if self._states[current.name]['terminal']:
            raise excp.InvalidState("Can not transition from terminal"
                                    " state '%s' on event '%s'" %
                                    (current.name, event))
        if event not in self._transitions[current.name]:
            raise excp.NotFound("Can not transition from state '%s' on"
                                " event '%s' (no defined transition)" %
                                (current.name, event))
        replacement = self._transitions[current.name][event]
        if current.on_exit is not None:
            current.on_exit(current.name, event)
        if replacement.on_enter is not None:
            replacement.on_enter(replacement.name, event)
        self._current = replacement
        return (
            self._states[replacement.name]['reactions'].get(event),
            self._states[replacement.name]['terminal'],
        )
Exemple #4
0
 def initialize(self):
     """Sets up the state machine (sets current state to start state...)."""
     if self._start_state not in self._states:
         raise excp.NotFound("Can not start from a undefined"
                             " state '%s'" % (self._start_state))
     if self._states[self._start_state]['terminal']:
         raise excp.InvalidState("Can not start from a terminal"
                                 " state '%s'" % (self._start_state))
     self._current = _Jump(self._start_state, None, None)
Exemple #5
0
def check_job_transition(old_state, new_state):
    """Check that job can transition from from ``old_state`` to ``new_state``.

    If transition can be performed, it returns true. If transition
    should be ignored, it returns false. If transition is not
    valid, it raises an InvalidState exception.
    """
    if old_state == new_state:
        return False
    pair = (old_state, new_state)
    if pair in _ALLOWED_JOB_TRANSITIONS:
        return True
    raise exc.InvalidState("Job transition from '%s' to '%s' is not allowed"
                           % pair)
Exemple #6
0
 def initialize(self):
     """Sets up the state machine (sets current state to start state...)."""
     if self._start_state not in self._states:
         raise excp.NotFound("Can not start from a undefined"
                             " state '%s'" % (self._start_state))
     if self._states[self._start_state]['terminal']:
         raise excp.InvalidState("Can not start from a terminal"
                                 " state '%s'" % (self._start_state))
     # No on enter will be called, since we are priming the state machine
     # and have not really transitioned from anything to get here, we will
     # though allow 'on_exit' to be called on the event that causes this
     # to be moved from...
     self._current = _Jump(self._start_state, None,
                           self._states[self._start_state]['on_exit'])
Exemple #7
0
def check_flow_transition(old_state, new_state):
    """Check that flow can transition from old_state to new_state.

    If transition can be performed, it returns True. If transition
    should be ignored, it returns False. If transition is not
    valid, it raises InvalidState exception.
    """
    if old_state == new_state:
        return False
    pair = (old_state, new_state)
    if pair in _ALLOWED_FLOW_TRANSITIONS:
        return True
    if pair in _IGNORED_FLOW_TRANSITIONS:
        return False
    raise exc.InvalidState("Flow transition from %s to %s is not allowed" %
                           pair)
Exemple #8
0
 def prepare(self):
     if not self._compiled:
         raise exc.InvalidState("Can not prepare an engine"
                                " which has not been compiled")
     if not self._storage_ensured:
         # Set our own state to resuming -> (ensure atoms exist
         # in storage) -> suspended in the storage unit and notify any
         # attached listeners of these changes.
         self._change_state(states.RESUMING)
         self._ensure_storage()
         self._change_state(states.SUSPENDED)
         self._storage_ensured = True
     # Reset everything back to pending (if we were previously reverted).
     if self.storage.get_flow_state() == states.REVERTED:
         self._runtime.reset_all()
         self._change_state(states.PENDING)
Exemple #9
0
def check_task_transition(old_state, new_state):
    """Check that task can transition from old_state to new_state.

    If transition can be performed, it returns True. If transition
    should be ignored, it returns False. If transition is not
    valid, it raises InvalidState exception.
    """
    pair = (old_state, new_state)
    if pair in _ALLOWED_TASK_TRANSITIONS:
        return True
    if pair in _IGNORED_TASK_TRANSITIONS:
        return False
    # TODO(harlowja): Should we check/allow for 3rd party states to be
    # triggered during RUNNING by having a concept of a sub-state that we also
    # verify against??
    raise exc.InvalidState("Task transition from %s to %s is not allowed" %
                           pair)
Exemple #10
0
 def prepare(self):
     if not self._compiled:
         raise exc.InvalidState("Can not prepare an engine"
                                " which has not been compiled")
     if not self._storage_ensured:
         self._ensure_storage()
         self._storage_ensured = True
     # At this point we can check to ensure all dependencies are either
     # flow/task provided or storage provided, if there are still missing
     # dependencies then this flow will fail at runtime (which we can avoid
     # by failing at preparation time).
     external_provides = set(self.storage.fetch_all().keys())
     missing = self._flow.requires - external_provides
     if missing:
         raise exc.MissingDependencies(self._flow, sorted(missing))
     # Reset everything back to pending (if we were previously reverted).
     if self.storage.get_flow_state() == states.REVERTED:
         self._runtime.reset_all()
         self._change_state(states.PENDING)
Exemple #11
0
    def transition(self, new_state):
        """Transitions the request to a new state.

        If transition was performed, it returns True. If transition
        should was ignored, it returns False. If transition was not
        valid (and will not be performed), it raises an InvalidState
        exception.
        """
        old_state = self._state
        if old_state == new_state:
            return False
        pair = (old_state, new_state)
        if pair not in _ALLOWED_TRANSITIONS:
            raise excp.InvalidState("Request transition from %s to %s is"
                                    " not allowed" % pair)
        if new_state in _STOP_TIMER_STATES:
            self._watch.stop()
        self._state = new_state
        LOG.debug("Transitioned '%s' from %s state to %s state", self,
                  old_state, new_state)
        return True
    def transition(self, new_state):
        """Transitions the request to a new state.

        If transition was performed, it returns True. If transition
        was ignored, it returns False. If transition was not
        valid (and will not be performed), it raises an InvalidState
        exception.
        """
        old_state = self._machine.current_state
        if old_state == new_state:
            return False
        try:
            self._machine.process_event(make_an_event(new_state))
        except (machine_excp.NotFound, machine_excp.InvalidState) as e:
            raise excp.InvalidState("Request transition from %s to %s is"
                                    " not allowed: %s" %
                                    (old_state, new_state, e))
        else:
            if new_state in STOP_TIMER_STATES:
                self._watch.stop()
            LOG.debug("Transitioned '%s' from %s state to %s state", self,
                      old_state, new_state)
            return True
Exemple #13
0
 def validate(self):
     if not self._storage_ensured:
         raise exc.InvalidState("Can not validate an engine"
                                " which has not has its storage"
                                " populated")
     # At this point we can check to ensure all dependencies are either
     # flow/task provided or storage provided, if there are still missing
     # dependencies then this flow will fail at runtime (which we can avoid
     # by failing at validation time).
     execution_graph = self._compilation.execution_graph
     if LOG.isEnabledFor(logging.BLATHER):
         LOG.blather(
             "Validating scoping and argument visibility for"
             " execution graph with %s nodes and %s edges with"
             " density %0.3f", execution_graph.number_of_nodes(),
             execution_graph.number_of_edges(), nx.density(execution_graph))
     missing = set()
     fetch = self.storage.fetch_unsatisfied_args
     for node in execution_graph.nodes_iter():
         missing.update(
             fetch(node.name, node.rebind, optional_args=node.optional))
     if missing:
         raise exc.MissingDependencies(self._flow, sorted(missing))
Exemple #14
0
 def suspend(self):
     if not self._compiled:
         raise exc.InvalidState("Can not suspend an engine"
                                " which has not been compiled")
     self._change_state(states.SUSPENDING)