loop over dnr nodes by topological sort

* Perform topological sort on graph nodes before looping over them to
mark do not run. This guarantees that parent nodes will be processed
before calling dependent child nodes. The complexity of the sorting is
N. The complexity of marking the the nodes is N*V
This commit is contained in:
chris meyers 2018-11-19 11:32:13 -05:00 committed by mabashian
parent cfa098479e
commit 7b087d4a6c
2 changed files with 26 additions and 6 deletions

View File

@ -1,3 +1,5 @@
from collections import deque
class SimpleDAG(object):
''' A simple implementation of a directed acyclic graph '''
@ -198,3 +200,26 @@ class SimpleDAG(object):
node_objs_visited.add(node_obj)
path.discard(node_obj)
return res
def sort_nodes_topological(self):
nodes_sorted = deque()
obj_ids_processed = set([])
def visit(node):
obj = node['node_object']
if obj.id in obj_ids_processed:
return
for child in self.get_dependencies(obj):
visit(child)
obj_ids_processed.add(obj.id)
nodes_sorted.appendleft(node)
for node in self.nodes:
obj = node['node_object']
if obj.id in obj_ids_processed:
continue
visit(node)
return nodes_sorted

View File

@ -1,6 +1,5 @@
# Python
import copy
from awx.main.models import (
WorkflowJobTemplateNode,
WorkflowJobNode,
@ -201,10 +200,9 @@ class WorkflowDAG(SimpleDAG):
def mark_dnr_nodes(self):
root_nodes = self.get_root_nodes()
nodes = copy.copy(root_nodes)
nodes_marked_do_not_run = []
for index, node in enumerate(nodes):
for node in self.sort_nodes_topological():
obj = node['node_object']
if obj.do_not_run is False and not obj.job:
@ -217,7 +215,4 @@ class WorkflowDAG(SimpleDAG):
obj.do_not_run = True
nodes_marked_do_not_run.append(node)
nodes.extend(self.get_dependencies(obj, 'success_nodes') +
self.get_dependencies(obj, 'failure_nodes') +
self.get_dependencies(obj, 'always_nodes'))
return [n['node_object'] for n in nodes_marked_do_not_run]