mirror of
https://github.com/ansible/awx.git
synced 2026-01-20 06:01:25 -03:30
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:
parent
cfa098479e
commit
7b087d4a6c
@ -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
|
||||
|
||||
@ -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]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user