Here we are going to discuss the algorithm that we use to execute a complex graph of blocks connected to each other (workflow).
In order to execute the above workflow of blocks, we use simple graph theory. The frontend provides a list of blocks and edges in the workflow, using which be build a graph. The graph is nothing but an adjacency list. Note that it is a directed graph.
To execute the workflow graph, we apply a simple BFS and execute the node we visit. But the problem arises when we visit a node whose all the input nodes are not visited (executed). So here the input for that node won’t be ready and we can’t execute that node.
Take the above graph as an example. When we apply a simple BFS, the visited sequence (as shown ubove each node in red) will be:
As you can see, we visited node H before G, which means we are trying to execute node H before we execute G. Here simple BFS fails as we need to execute node G before node H as node G’s output is connected to node H’s input.
Hence we use modified BFS. Here, with the adjacency list, we also keep the adjacency list of the transpose of the graph. The adjacency list of the transpose of the graph will tell us all the inputs to a node whereas the normal adjacency list will tell us outputs from that node.
adjacency_list = { | transpose_adjacency_list = {
A: -> D | A:
B: -> D, E, F | B:
C: -> F | C:
D: -> H | D: -> A, B
E: -> H | E: -> B
F: -> G | F: -> B, C
G: -> H | G: -> F
H: | H: -> D, E, G
} | }
So, in modified BFS, when we are going to visit a node, we mark it as visited if all it’s input nodes are also visited. We get the input nodes for that node from transpose_adjacency_list. If even one of the input nodes is not visited, we mark the node not-visited and continue with the BFS. By doing this, we assure that all the input nodes to that node are visited.
Taking the example of the above graph, visited sequence will be: