diff --git a/awx/main/scheduler/dag_workflow.py b/awx/main/scheduler/dag_workflow.py index 9c3cb3cc4e..8e1cb14113 100644 --- a/awx/main/scheduler/dag_workflow.py +++ b/awx/main/scheduler/dag_workflow.py @@ -70,20 +70,32 @@ class WorkflowDAG(SimpleDAG): return True def bfs_nodes_to_run(self): + nodes = self.get_root_nodes() nodes_found = [] + node_ids_visited = set() + + for index, n in enumerate(nodes): + obj = n['node_object'] + if obj.id in node_ids_visited: + continue + node_ids_visited.add(obj.id) - for node in self.sort_nodes_topological(): - obj = node['node_object'] if obj.do_not_run is True: continue - elif obj.job: - continue + + if obj.job: + if obj.job.status in ['failed', 'error', 'canceled']: + nodes.extend(self.get_dependencies(obj, 'failure_nodes') + + self.get_dependencies(obj, 'always_nodes')) + elif obj.job.status == 'successful': + nodes.extend(self.get_dependencies(obj, 'success_nodes') + + self.get_dependencies(obj, 'always_nodes')) elif obj.unified_job_template is None: - continue - - if self._are_relevant_parents_finished(node): - nodes_found.append(node) - + nodes.extend(self.get_dependencies(obj, 'failure_nodes') + + self.get_dependencies(obj, 'always_nodes')) + else: + if self._are_relevant_parents_finished(n): + nodes_found.append(n) return [n['node_object'] for n in nodes_found] def cancel_node_jobs(self):