This is a sketch of starting and configuring provider instances once they
are needed and then closing them once they are no longer needed. The
stubby implementation of data resource instance planning is there mainly
just to illustrate how this is intended to work, but it's not yet complete
enough to actually function.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
Previously this had the idea that the planning engine would work in two
subphases where first it would deal with the desired state (decided by
evaluating the configuration) and then it would do a second pass to plan
to delete any resource instances that didn't show up in the desired state.
Although that would technically work, we need to keep configured provider
instances open for the whole timespan between planning the first
desired resource instance and the final orphan instance using each
provider, and so splitting into two phases effectively means we'd have
provider instances sitting open but idle waiting for the desired state
subphase to complete to learn if they are needed for the orphan subphase.
This commit stubs out (but does not yet implement) a new approach where
the orphan planning can happen concurrently with the desired state
planning. This works by having the evaluator gradually describe to the
planning engine which module calls, module call instances, resources, and
resource instances _are_ present in the desired state -- as soon as that
information becomes available -- so that the planning engine can notice
by omission what subset of the prior state resource instances are no longer
desired and are therefore orphans.
This means that the planning engine should now have all of the information
it needs to recognize when a provider can be closed: the PlanningOracle
reports which _desired_ resource instances (or placeholders thereof) are
expected to need each provider instance, and the prior state tracks
exactly which provider instance each prior resource instance was associated
with, and so a provider's work is finished once all instances in the union
of those two sets have had their action planned.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
As was already noted in a comment in the PlanningOracle declaration, the
PlanningOracle API is an exported entrypoint usable from outside lang/eval
and so each exported method should establish its own workgraph worker to
make sure it's handling those concerns correctly regardless of how the
caller chooses to use them.
For example, a caller might choose to make concurrent calls into the oracle
from multiple goroutines, which would violate the assumption that each
concurrently-running codepath is associated with a separate workgraph
worker.
Even if a caller is managing their own workgraph workers in the expected
way, this is functionally harmless and relatively cheap.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This is a building block for use by a planning engine implemented elsewhere
in OpenTofu so that it can be notified (by the completion of a call to the
function) when all resource instances that use a particular provider
instance or ephemeral resource instance have completed their plan-time
evaluation work.
Existing methods of PlanningOracle already expose sets of addresses to
wait for, but this method is separate from those because the planning
engine also needs the dependency information as data to know when an
ephemeral resource instance might need to be left open beyond the part of
the planning process driven by lang/eval in order to plan the delete
actions for any "orphan" resource instances that are in the prior state
but no longer declared in the configuration.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
Continuing to split up some of the source files that have grown long over
ongoing experimentation, this is the start of splitting the config_plan.go
file into smaller parts.
For now only PlanningOracle gets its own file, but other types related to
planning might follow in later commits.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>