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

Finish implementation of unknown count/for_each in data sources #35122

Merged
merged 5 commits into from May 9, 2024

Conversation

nfagerlund
Copy link
Collaborator

This PR adds tests for deferring data sources due to unknown count/for_each values, and makes the necessary behavior changes to get those tests passing.

For reviewers: here's the main things to validate about this PR.

  • Is it logically and practically sound to always set deferralAllowed = true in applies? If not, can we think of a safer way to re-process data sources that should be deferred (preferably without significantly changing the semantics of the plan)?
  • Does it make sense for Deferred's informational methods to do early negative returns if deferralAllowed == false?
  • Can we think of any additional ways to directly or indirectly observe the effect of deferring a data source? I had a brief thought about spying on data source read requests in the mock provider, but in practice it turned out to be kinda awkward and not informative enough. More iteration might make something useful of it, tho. 🤔

Target Release

1.9.x

Draft CHANGELOG entry

EXPERIMENTS

The deferred actions experiment now supports deferring data sources due to unknown count/for_each values.

I checked this with James, and it was to temporarily speed up test cycle times
on a slippery bug.
…Allowed`

Some of the methods on `Deferred` were using `d.externalDependencyDeferred` to
report whether some items were deferred, without first checking that
`d.deferralAllowed` was even turned on. Then, to accommodate that, we were
making sure to only pass the external dependency deferral signal (AKA the whole
component is deferred) in to the `Deferred` struct if deferral is allowed.

This was an artifact of the order things got implemented in; the "is thing
deferred" checks predated the `deferralAllowed` field, and the call sites of
those methods were behind other guards at the time.

Anyway, this commit flips things so we now always propagate the received
`ExternalDependencyDeferred` value in to the `Deferred`, but the `Deferred`
takes the global on/off switch into account before relying on that value for its
final answers about a given possible deferral.
This should be sound 100% of the time, because the only way anything can be
deferred in an apply is if we _planned_ to defer it... in other words, if
deferral was allowed during the plan.

The reason we need this enabled is to allow proper construction of wildcard key
addresses for data sources that are deferred due to unknown count or for_each
values. Unlike with resources, we don't have a convenient space in the plan to
stash info about a data source deferral; data sources don't have "planned
changes" per se (they're unmanaged and thus can't be changed), so they don't
result in a "deferred change" and must be re-checked during the apply.

However, since applies are relying on the plan's info about deferred _actual_
changes, they don't need to construct the (still somewhat expensive) resource
graph, so we should opt them out of that graph construction to avoid a
performance regression.
@nfagerlund nfagerlund marked this pull request as ready for review May 7, 2024 02:17
@jbardin
Copy link
Member

jbardin commented May 8, 2024

I think you will need to look for a deferred data source by checking for the absence of the other options.

  • If the data source is read during the plan it will be updated in the planned state.
  • If the data source is not deferred in the stacks sense and will be read during apply (historically we have sometimes called a data source which will be read during apply "deferred", so there may be code which uses that terminology elsewhere), and the plan will have a change with ResourceInstanceReadBecauseConfigUnknown (?) or ResourceInstanceReadBecauseDependencyPending (!).

I think the short circuit if !d.deferralAllowed are OK for now from a code safety perspective, and we can figure out if those should have been called at all separately.

I also think allowing deferralAllowed = true during apply should be fine, because apply can't cause any deferrals itself, it can only do what's been planned. In the long run I think it would be better if we can eliminate the extra branching anyway, but it's fine for now as we try to slowly integrate into the existing codebase.

@nfagerlund nfagerlund merged commit 20d53ce into main May 9, 2024
6 checks passed
@nfagerlund nfagerlund deleted the nf/apr24-validate-data-source-foreach branch May 9, 2024 18:33
Copy link

github-actions bot commented May 9, 2024

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

@nfagerlund
Copy link
Collaborator Author

(Changelog already has a line to this effect, so I'm leaving it be.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants