Allow any of the previous tasks to satisfy requirements.

Instead of just checking the previous task, allow any of the
previous tasks to provide the requirement for a new task.
This commit is contained in:
Joshua Harlow
2013-05-22 14:51:03 -07:00
parent d4f74720cb
commit afea4f0732

View File

@@ -33,7 +33,7 @@ def _convert_to_set(items):
class Flow(ordered_flow.Flow): class Flow(ordered_flow.Flow):
"""A linear chain of tasks that can be applied as one unit or """A linear chain of tasks that can be applied as one unit or
rolled back as one unit. Each task in the chain may have requirements rolled back as one unit. Each task in the chain may have requirements
which are satisfied by the previous task in the chain.""" which are satisfied by the previous task/s in the chain."""
def __init__(self, name, tolerant=False, parents=None): def __init__(self, name, tolerant=False, parents=None):
super(Flow, self).__init__(name, tolerant, parents) super(Flow, self).__init__(name, tolerant, parents)
@@ -41,31 +41,35 @@ class Flow(ordered_flow.Flow):
def _fetch_task_inputs(self, task): def _fetch_task_inputs(self, task):
inputs = {} inputs = {}
if self.results: for r in _convert_to_set(task.requires()):
(_last_task, last_results) = self.results[-1] # Find the last task that provided this.
for k in task.requires(): for (last_task, last_results) in reversed(self.results):
if last_results and k in last_results: if r not in _convert_to_set(last_task.provides()):
inputs[k] = last_results[k] continue
if last_results and r in last_results:
inputs[r] = last_results[r]
else:
inputs[r] = None
# Some task said they had it, get the next requirement.
break
return inputs return inputs
def _validate_provides(self, task): def _validate_provides(self, task):
requires = _convert_to_set(task.requires()) # Ensure that some previous task provides this input.
last_provides = set() missing_requires = []
last_provider = None for r in _convert_to_set(task.requires()):
if self._tasks: found_provider = False
last_provider = self._tasks[-1] for prev_task in reversed(self._tasks):
last_provides = _convert_to_set(last_provider.provides()) if r in _convert_to_set(prev_task.provides()):
found_provider = True
break
if not found_provider:
missing_requires.append(r)
# Ensure that the last task provides all the needed input for this # Ensure that the last task provides all the needed input for this
# task to run correctly. # task to run correctly.
req_diff = requires.difference(last_provides) if len(missing_requires):
if req_diff:
if last_provider is None:
msg = ("There is no previous task providing the outputs %s" msg = ("There is no previous task providing the outputs %s"
" for %s to correctly execute.") % (req_diff, task) " for %s to correctly execute.") % (missing_requires, task)
else:
msg = ("%s does not provide the needed outputs %s for %s to"
" correctly execute.")
msg = msg % (last_provider, req_diff, task)
raise exc.InvalidStateException(msg) raise exc.InvalidStateException(msg)
def add(self, task): def add(self, task):