Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

topological sorting for refactoring #31499

Merged
merged 4 commits into from Jul 22, 2022
Merged

topological sorting for refactoring #31499

merged 4 commits into from Jul 22, 2022

Conversation

jbardin
Copy link
Member

@jbardin jbardin commented Jul 22, 2022

In order to traverse a graph in "dependency order", meaning all dependencies of a node have been visited before the node itself is visited, you need to first create a topological sort of the graph nodes. Terraform core has always done this, accomplishing the sort through a parallel walk of all nodes, with each node becoming unblocked as soon as dependencies are satisfied, naturally creating a topological order for the visits. There however was no simple synchronous walk function which provided the same ordering of nodes. This led the refactoring package to erroneously use the only type of synchronous walk available, ReverseDepthFirstWalk. Since the majority of move graphs reduce into a simple tree, the depth-first walk appears to be correct at first glance, however if you take a simple diamond shaped graph like so:

  1
 / \
2   3
 \ /
  4

You can see that a depth-first walk from the top cannot work, since 4 is always going to be visited before one of it's dependencies, otherwise it would not be depth-first. (Note that breadth-first appears to work in this case, but that will just fail for differently shaped graphs where a node can be found at different depths via different paths, since breadth-first is also not a topological sort.)

Add TopologicalOrder and ReverseTopologicalOrder methods to dag.AcyclicGraph, returning a sorted slice which can be used to visit the nodes in an order ensuring dependencies will always be satisfied. During the dag package refactoring, additional breadth-first walks were also added for comparison and additional test coverage.

Use ReverseTopologicalSort in the refactoring package and iterate directly over each move statement. We can refactor this test too, removing all the address literals and parsing them directly from the test fixture.

Fixes #31489.

Make DAG walks test-able, and add tests for more complex graph ordering.
We also add breadth-first for comparison, though it's not used currently
in Terraform.
A topological walk was previously only done in Terraform via the
concurrent method used for walking the primary dependency graph in core.
Sometime however we want a dependency ordering without the overhead of
instantiating the concurrent walk with the channel-based edges.

Add TopologicalOrder and ReverseTopologicalOrder to obtain a list of
nodes which can be used to visit each while ensuring that all
dependencies are satisfied.
The dag package did not previously provide a topological walk of a given
graph. While the existing combination of a transitive reduction with a
depth-first walk appeared to accomplish this, depth-first is only
equivalent with a simple tree. If there are multiple paths to a node, a
depth-first approach will skip dependencies from alternate paths.
@jbardin jbardin merged commit 8b1b05f into main Jul 22, 2022
@jbardin jbardin deleted the jbardin/dag-walks branch July 22, 2022 19:41
@github-actions
Copy link

Reminder for the merging maintainer: if this is a user-visible change, please update the changelog on the appropriate release branch.

jbardin added a commit that referenced this pull request Jul 22, 2022
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Moved block ordering possibly incorrect for module with multiple previously moved resources
2 participants