def _walk_edge_deciders(self, graph, atom):
        """Iterates through all nodes, deciders that alter atoms execution."""
        # This is basically a reverse breadth first exploration, with
        # special logic to further traverse down flow nodes as needed...
        predecessors_iter = graph.predecessors_iter
        nodes = collections.deque((u_node, atom)
                                  for u_node in predecessors_iter(atom))
        visited = set()
        while nodes:
            u_node, v_node = nodes.popleft()
            u_node_kind = graph.node[u_node]['kind']
            u_v_data = graph.adj[u_node][v_node]
            try:
                decider = u_v_data[LINK_DECIDER]
                decider_depth = u_v_data.get(LINK_DECIDER_DEPTH)
                if decider_depth is None:
                    decider_depth = de.Depth.ALL
                yield _EdgeDecider(u_node, u_node_kind,
                                   decider, decider_depth)
            except KeyError:
                pass
            if u_node_kind == com.FLOW and u_node not in visited:
                # Avoid re-exploring the same flow if we get to this same
                # flow by a different *future* path...
                visited.add(u_node)
                # Since we *currently* jump over flow node(s), we need to make
                # sure that any prior decider that was directed at this flow
                # node also gets used during future decisions about this
                # atom node.
                nodes.extend((u_u_node, u_node)
                             for u_u_node in predecessors_iter(u_node))
dataset/ETHPy150Open openstack/taskflow/taskflow/engines/action_engine/runtime.py/Runtime._walk_edge_deciders/original