Add the ability to skip resolving from activating

It can be useful for debugging a failure to be able
to stop when a failure is detected so that the failure
can be examined in more detail.

This adds the ability to have a 'never_resolve' engine
option which will skip such resolution attempts for
these types of scenarios.

Change-Id: If2386cba970e14c7168a6ff2d4fd4786bcd8e989
This commit is contained in:
Joshua Harlow
2016-04-04 17:08:23 -07:00
parent 29ba91e93f
commit ddf58ff79a
2 changed files with 25 additions and 10 deletions

View File

@@ -111,6 +111,8 @@ class Completer(object):
self._undefined_resolver = RevertAll(self._runtime) self._undefined_resolver = RevertAll(self._runtime)
self._defer_reverts = strutils.bool_from_string( self._defer_reverts = strutils.bool_from_string(
self._runtime.options.get('defer_reverts', False)) self._runtime.options.get('defer_reverts', False))
self._resolve = not strutils.bool_from_string(
self._runtime.options.get('never_resolve', False))
def resume(self): def resume(self):
"""Resumes atoms in the contained graph. """Resumes atoms in the contained graph.
@@ -126,12 +128,15 @@ class Completer(object):
atoms = list(self._analyzer.iterate_nodes(co.ATOMS)) atoms = list(self._analyzer.iterate_nodes(co.ATOMS))
atom_states = self._storage.get_atoms_states(atom.name atom_states = self._storage.get_atoms_states(atom.name
for atom in atoms) for atom in atoms)
if self._resolve:
for atom in atoms: for atom in atoms:
atom_state, _atom_intention = atom_states[atom.name] atom_state, _atom_intention = atom_states[atom.name]
if atom_state == st.FAILURE: if atom_state == st.FAILURE:
self._process_atom_failure(atom, self._storage.get(atom.name)) self._process_atom_failure(
atom, self._storage.get(atom.name))
for retry in self._analyzer.iterate_retries(st.RETRYING): for retry in self._analyzer.iterate_retries(st.RETRYING):
for atom, state, intention in self._runtime.retry_subflow(retry): retry_affected_atoms_it = self._runtime.retry_subflow(retry)
for atom, state, intention in retry_affected_atoms_it:
if state: if state:
atom_states[atom.name] = (state, intention) atom_states[atom.name] = (state, intention)
unfinished_atoms = set() unfinished_atoms = set()
@@ -149,12 +154,13 @@ class Completer(object):
Returns whether the result should be saved into an accumulator of Returns whether the result should be saved into an accumulator of
failures or whether this should not be done. failures or whether this should not be done.
""" """
if outcome == ex.EXECUTED: if outcome == ex.EXECUTED and self._resolve:
self._process_atom_failure(node, failure) self._process_atom_failure(node, failure)
# We resolved something, carry on... # We resolved something, carry on...
return False return False
else: else:
# Reverting failed, always retain the failure... # Reverting failed (or resolving was turned off), always
# retain the failure...
return True return True
def complete(self, node, outcome, result): def complete(self, node, outcome, result):

View File

@@ -116,6 +116,15 @@ class ActionEngine(base.Engine):
| | has a separate retry | | | | | has a separate retry | | |
| | behavior). | | | | | behavior). | | |
+----------------------+-----------------------+------+------------+ +----------------------+-----------------------+------+------------+
| ``never_resolve`` | When true, instead | bool | ``False`` |
| | of reverting | | |
| | and trying to resolve | | |
| | a atom failure the | | |
| | engine will skip | | |
| | reverting and abort | | |
| | instead of reverting | | |
| | and/or retrying. | | |
+----------------------+-----------------------+------+------------+
| ``inject_transient`` | When true, values | bool | ``True`` | | ``inject_transient`` | When true, values | bool | ``True`` |
| | that are local to | | | | | that are local to | | |
| | each atoms scope | | | | | each atoms scope | | |