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

core: Simplify our idea of "root node" and require it for DynamicExpand #31880

Merged
merged 1 commit into from Oct 13, 2022

Conversation

apparentlymart
Copy link
Member

@apparentlymart apparentlymart commented Sep 27, 2022

The graph walking mechanism is specified as requiring a graph with a single root, which in practice means there's exactly one node in the graph which doesn't have any dependencies.

However, we previously weren't verifying that invariant is true for subgraphs returned from DynamicExpand. It was working anyway, but it's not ideal to be relying on a behavior that isn't guaranteed by our underlying infrastructure.

We also previously had the RootTransformer being a bit clever and trying to avoid adding a new node if there is already only a single graph with no dependencies. That special case isn't particularly valuable since there's no harm in turning a one-node graph into a two-node graph with an explicit separate root node, and doing that allows us to assume that the root node is always present and is always exactly terraform.rootNode.

Many existing DynamicExpand implementations were not producing valid graphs and were previously getting away with it. All of them now produce properly-rooted graphs that should pass validation, and we will guarantee that with an explicit check of the DynamicExpand return value before we try to walk that subgraph. For good measure we also verify that the root node is exactly terraform.rootNode, even though that isn't strictly required by our graph walker, just to help us catch potential future bugs where a DynamicExpand implementation neglects to add our singleton root node.


This is not a user-facing change; if this alters Terraform's outwardly-visible behavior (apart from the detailed logs) then that's a bug.

Instead, it's addressing an implementation quirk we noticed in review of #31860, where the initial implementation was not producing a valid subgraph in all cases due to the combination of our "clever" behavior in RootTransformer and the new Graph.Subsume method which didn't take that into account.

This is therefore another attempt to remove some special cases and overall make Terraform Core's behavior easier to think about: we can now assume that all graphs will contain terraform.rootNode and that it will be the only node which has no dependencies itself. We can also assume that all graphs, including dynamic sub-graphs, will be "valid" per the definition in the Validate method.

I'm intentionally not backporting this into the v1.3 branch because it isn't strictly necessary to fix the previously-discovered bug and so it's better to let this soak during the alpha and beta releases for v1.4 in case there's any unintended consequences we haven't considered yet.

The graph walking mechanism is specified as requiring a graph with a single
root, which in practice means there's exactly one node in the graph
which doesn't have any dependencies.

However, we previously weren't verifying that invariant is true for
subgraphs returned from DynamicExpand. It was working anyway, but it's not
ideal to be relying on a behavior that isn't guaranteed by our underlying
infrastructure.

We also previously had the RootTransformer being a bit clever and trying
to avoid adding a new node if there is already only a single graph with
no dependencies. That special case isn't particularly valuable since
there's no harm in turning a one-node graph into a two-node graph with
an explicit separate root node, and doing that allows us to assume that
the root node is always present and is always exactly terraform.rootNode.

Many existing DynamicExpand implementations were not producing valid
graphs and were previously getting away with it. All of them now produce
properly-rooted graphs that should pass validation, and we will guarantee
that with an explicit check of the DynamicExpand return value before we
try to walk that subgraph. For good measure we also verify that the root
node is exactly terraform.rootNode, even though that isn't strictly
required by our graph walker, just to help us catch potential future bugs
where a DynamicExpand implementation neglects to add our singleton root
node.
@jbardin
Copy link
Member

jbardin commented Sep 28, 2022

The fact that Validate requires a root node is left over from very early on. There's no reason a dag must have a single root, and in fact all the synchronous walk functions take a set of roots. I only carried the root node forward during the large refactors to reduce churn when it presented no problems. What I'm getting at is, would it be simpler to just get rid of it now entirely, or is it still used somehow?

@apparentlymart
Copy link
Member Author

My focus here was on trying to make all of the existing implementations obey the documented contract rather than changing the contract, so I've not investigated what the consequences would be of changing the contract (if any).

I don't personally feel confident in evaluating all of the possible problems that removing this root node might have, since this has been with us since long before I was working on Terraform and so I don't know what exactly depends on it. If we can feel sure that we're already exercising all of the relevant behaviors in our test suite then it could be interesting to give it a try, but I've been burned before by things that have been around long enough that we just take it for granted and don't test it thoroughly in our test suite. 🤔

Copy link
Member

@jbardin jbardin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I thought we already merged this!
I think it's fine to at least make the usage consistent before we consider investigating removing it.

@apparentlymart apparentlymart merged commit 4bc1696 into main Oct 13, 2022
@apparentlymart apparentlymart deleted the f-core-validate-subgraph branch October 13, 2022 21:01
@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.

@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 Nov 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants