Add logging around metadata, ignore tallying + history

This can be useful to look at for debugging purposes
when trying to understand how (and if) a atom is being
ignored by a set of deciders.

Change-Id: I550a2f7f361e516c255683d725b2f3a8130a0a86
This commit is contained in:
Joshua Harlow
2016-08-01 13:16:51 -07:00
committed by Joshua Harlow
parent 8eed13c62b
commit b4ab7c4ef4
2 changed files with 47 additions and 24 deletions

View File

@@ -22,8 +22,11 @@ import six
from taskflow import deciders from taskflow import deciders
from taskflow.engines.action_engine import compiler from taskflow.engines.action_engine import compiler
from taskflow.engines.action_engine import traversal from taskflow.engines.action_engine import traversal
from taskflow import logging
from taskflow import states from taskflow import states
LOG = logging.getLogger(__name__)
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class Decider(object): class Decider(object):
@@ -119,31 +122,46 @@ class IgnoreDecider(Decider):
self._edge_deciders = edge_deciders self._edge_deciders = edge_deciders
def tally(self, runtime): def tally(self, runtime):
if not self._edge_deciders: voters = {
return [] 'run_it': [],
# Gather all atoms (the ones that were not ignored) results so that 'do_not_run_it': [],
# those results can be used 'ignored': [],
# by the decider(s) that are making a decision as to pass or }
# not pass...
states_intentions = runtime.storage.get_atoms_states(
ed.from_node.name for ed in self._edge_deciders
if ed.kind in compiler.ATOMS)
history = {} history = {}
for atom_name in six.iterkeys(states_intentions): if self._edge_deciders:
atom_state, _atom_intention = states_intentions[atom_name] # Gather all atoms (the ones that were not ignored) results so
if atom_state != states.IGNORE: # that those results can be used by the decider(s) that are
history[atom_name] = runtime.storage.get(atom_name) # making a decision as to pass or not pass...
nay_voters = [] states_intentions = runtime.storage.get_atoms_states(
for ed in self._edge_deciders: ed.from_node.name for ed in self._edge_deciders
if (ed.kind in compiler.ATOMS and if ed.kind in compiler.ATOMS)
# It was an ignored atom (not included in history and the for atom_name in six.iterkeys(states_intentions):
# only way that is possible is via above loop skipping atom_state, _atom_intention = states_intentions[atom_name]
# it...) if atom_state != states.IGNORE:
ed.from_node.name not in history): history[atom_name] = runtime.storage.get(atom_name)
continue for ed in self._edge_deciders:
if not ed.decider(history=history): if (ed.kind in compiler.ATOMS and
nay_voters.append(ed) # It was an ignored atom (not included in history and
return nay_voters # the only way that is possible is via above loop
# skipping it...)
ed.from_node.name not in history):
voters['ignored'].append(ed)
continue
if not ed.decider(history=history):
voters['do_not_run_it'].append(ed)
else:
voters['run_it'].append(ed)
if LOG.isEnabledFor(logging.TRACE):
LOG.trace("Out of %s deciders there were %s 'do no run it'"
" voters, %s 'do run it' voters and %s 'ignored'"
" voters for transition to atom '%s' given history %s",
sum(len(eds) for eds in six.itervalues(voters)),
list(ed.from_node.name
for ed in voters['do_not_run_it']),
list(ed.from_node.name for ed in voters['run_it']),
list(ed.from_node.name for ed in voters['ignored']),
self._atom.name, history)
return voters['do_not_run_it']
def affect(self, runtime, nay_voters): def affect(self, runtime, nay_voters):
# If there were many 'nay' edge deciders that were targeted # If there were many 'nay' edge deciders that were targeted

View File

@@ -30,6 +30,7 @@ from taskflow.engines.action_engine import scheduler as sched
from taskflow.engines.action_engine import scopes as sc from taskflow.engines.action_engine import scopes as sc
from taskflow.engines.action_engine import traversal as tr from taskflow.engines.action_engine import traversal as tr
from taskflow import exceptions as exc from taskflow import exceptions as exc
from taskflow import logging
from taskflow import states as st from taskflow import states as st
from taskflow.utils import misc from taskflow.utils import misc
@@ -39,6 +40,8 @@ from taskflow.flow import (LINK_DECIDER, LINK_DECIDER_DEPTH) # noqa
_EdgeDecider = collections.namedtuple('_EdgeDecider', _EdgeDecider = collections.namedtuple('_EdgeDecider',
'from_node,kind,decider,depth') 'from_node,kind,decider,depth')
LOG = logging.getLogger(__name__)
class Runtime(object): class Runtime(object):
"""A aggregate of runtime objects, properties, ... used during execution. """A aggregate of runtime objects, properties, ... used during execution.
@@ -139,6 +142,8 @@ class Runtime(object):
metadata['scheduler'] = scheduler metadata['scheduler'] = scheduler
metadata['edge_deciders'] = tuple(deciders_it) metadata['edge_deciders'] = tuple(deciders_it)
metadata['action'] = action metadata['action'] = action
LOG.trace("Compiled %s metadata for node %s (%s)",
metadata, node.name, node_kind)
self._atom_cache[node.name] = metadata self._atom_cache[node.name] = metadata
# TODO(harlowja): optimize the different decider depths to avoid # TODO(harlowja): optimize the different decider depths to avoid
# repeated full successor searching; this can be done by searching # repeated full successor searching; this can be done by searching