summaryrefslogtreecommitdiff
path: root/taskflow/formatters.py
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2015-11-16 16:27:42 -0800
committerJoshua Harlow <harlowja@gmail.com>2016-01-09 22:42:17 -0800
commit8e8156c488dea8ae876b112c30e41e60da4f5be7 (patch)
treea4c119dda7d2338bd8c63aad593bbb42d24f3e1f /taskflow/formatters.py
parentf555a35f3081ba492db15d7bda11fbe50f2a8349 (diff)
downloadtaskflow-8e8156c488dea8ae876b112c30e41e60da4f5be7.tar.gz
Allow for alterations in decider 'area of influence'
Christmas came early. Closes-Bug: #1479466 Change-Id: I931d826690c925f022dbfffe9afb7bf41345b1d0
Diffstat (limited to 'taskflow/formatters.py')
-rw-r--r--taskflow/formatters.py123
1 files changed, 59 insertions, 64 deletions
diff --git a/taskflow/formatters.py b/taskflow/formatters.py
index 41b409c..af6c6a5 100644
--- a/taskflow/formatters.py
+++ b/taskflow/formatters.py
@@ -42,16 +42,20 @@ def _fetch_predecessor_tree(graph, atom):
"""Creates a tree of predecessors, rooted at given atom."""
root = tree.Node(atom)
stack = [(root, atom)]
- seen = set()
while stack:
parent, node = stack.pop()
for pred_node in graph.predecessors_iter(node):
- child = tree.Node(pred_node,
- **graph.node[pred_node])
- parent.add(child)
- stack.append((child, pred_node))
- seen.add(pred_node)
- return len(seen), root
+ pred_node_data = graph.node[pred_node]
+ if pred_node_data['kind'] == compiler.FLOW_END:
+ # Jump over and/or don't show flow end nodes...
+ for pred_pred_node in graph.predecessors_iter(pred_node):
+ stack.append((parent, pred_pred_node))
+ else:
+ child = tree.Node(pred_node, **pred_node_data)
+ parent.add(child)
+ # And go further backwards...
+ stack.append((child, pred_node))
+ return root
class FailureFormatter(object):
@@ -64,59 +68,51 @@ class FailureFormatter(object):
def __init__(self, engine, hide_inputs_outputs_of=()):
self._hide_inputs_outputs_of = hide_inputs_outputs_of
self._engine = engine
- self._formatter_funcs = {
- compiler.FLOW: self._format_flow,
- }
- for kind in compiler.ATOMS:
- self._formatter_funcs[kind] = self._format_atom
-
- def _format_atom(self, storage, cache, node):
- """Formats a single tree node (atom) into a string version."""
- atom = node.item
- atom_name = atom.name
- atom_attrs = {}
- intention, intention_found = _cached_get(cache, 'intentions',
- atom_name,
- storage.get_atom_intention,
- atom_name)
- if intention_found:
- atom_attrs['intention'] = intention
- state, state_found = _cached_get(cache, 'states', atom_name,
- storage.get_atom_state, atom_name)
- if state_found:
- atom_attrs['state'] = state
- if atom_name not in self._hide_inputs_outputs_of:
- # When the cache does not exist for this atom this
- # will be called with the rest of these arguments
- # used to populate the cache.
- fetch_mapped_args = functools.partial(
- storage.fetch_mapped_args, atom.rebind,
- atom_name=atom_name, optional_args=atom.optional)
- requires, requires_found = _cached_get(cache, 'requires',
- atom_name,
- fetch_mapped_args)
- if requires_found:
- atom_attrs['requires'] = requires
- provides, provides_found = _cached_get(cache, 'provides',
- atom_name,
- storage.get_execute_result,
- atom_name)
- if provides_found:
- atom_attrs['provides'] = provides
- if atom_attrs:
- return "Atom '%s' %s" % (atom_name, atom_attrs)
- else:
- return "Atom '%s'" % (atom_name)
-
- def _format_flow(self, storage, cache, node):
- """Formats a single tree node (flow) into a string version."""
- flow = node.item
- return flow.name
def _format_node(self, storage, cache, node):
"""Formats a single tree node into a string version."""
- formatter_func = self. _formatter_funcs[node.metadata['kind']]
- return formatter_func(storage, cache, node)
+ if node.metadata['kind'] == compiler.FLOW:
+ flow = node.item
+ flow_name = flow.name
+ return "Flow '%s'" % (flow_name)
+ elif node.metadata['kind'] in compiler.ATOMS:
+ atom = node.item
+ atom_name = atom.name
+ atom_attrs = {}
+ intention, intention_found = _cached_get(
+ cache, 'intentions', atom_name, storage.get_atom_intention,
+ atom_name)
+ if intention_found:
+ atom_attrs['intention'] = intention
+ state, state_found = _cached_get(cache, 'states', atom_name,
+ storage.get_atom_state,
+ atom_name)
+ if state_found:
+ atom_attrs['state'] = state
+ if atom_name not in self._hide_inputs_outputs_of:
+ # When the cache does not exist for this atom this
+ # will be called with the rest of these arguments
+ # used to populate the cache.
+ fetch_mapped_args = functools.partial(
+ storage.fetch_mapped_args, atom.rebind,
+ atom_name=atom_name, optional_args=atom.optional)
+ requires, requires_found = _cached_get(cache, 'requires',
+ atom_name,
+ fetch_mapped_args)
+ if requires_found:
+ atom_attrs['requires'] = requires
+ provides, provides_found = _cached_get(
+ cache, 'provides', atom_name,
+ storage.get_execute_result, atom_name)
+ if provides_found:
+ atom_attrs['provides'] = provides
+ if atom_attrs:
+ return "Atom '%s' %s" % (atom_name, atom_attrs)
+ else:
+ return "Atom '%s'" % (atom_name)
+ else:
+ raise TypeError("Unable to format node, unknown node"
+ " kind '%s' encountered" % node.metadata['kind'])
def format(self, fail, atom_matcher):
"""Returns a (exc_info, details) tuple about the failure.
@@ -143,13 +139,11 @@ class FailureFormatter(object):
graph = compilation.execution_graph
atom_node = hierarchy.find_first_match(atom_matcher)
atom = None
- priors = 0
atom_intention = None
if atom_node is not None:
atom = atom_node.item
atom_intention = storage.get_atom_intention(atom.name)
- priors = sum(c for (_n, c) in graph.in_degree_iter([atom]))
- if atom is not None and priors and atom_intention in self._BUILDERS:
+ if atom is not None and atom_intention in self._BUILDERS:
# Cache as much as we can, since the path of various atoms
# may cause the same atom to be seen repeatedly depending on
# the graph structure...
@@ -160,12 +154,13 @@ class FailureFormatter(object):
'states': {},
}
builder, kind = self._BUILDERS[atom_intention]
- count, rooted_tree = builder(graph, atom)
- buff.write_nl('%s %s (most recent atoms first):' % (count, kind))
+ rooted_tree = builder(graph, atom)
+ child_count = rooted_tree.child_count(only_direct=False)
+ buff.write_nl('%s %s (most recent first):' % (child_count, kind))
formatter = functools.partial(self._format_node, storage, cache)
- child_count = rooted_tree.child_count()
+ direct_child_count = rooted_tree.child_count(only_direct=True)
for i, child in enumerate(rooted_tree, 1):
- if i == child_count:
+ if i == direct_child_count:
buff.write(child.pformat(stringify_node=formatter,
starting_prefix=" "))
else: