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

helper/schema: Add SchemaFunc field to Resource type #1218

Merged
merged 1 commit into from
Jun 28, 2023
Merged

Conversation

bflad
Copy link
Contributor

@bflad bflad commented Jun 23, 2023

Closes #1217

This change introduces a new SchemaFunc field and SchemaMap method to the Resource type. Currently, the Schema field data of all Resource is held in memory for the lifecycle of the provider server, which is problematic for providers with many resources and/or larger schemas in resources. The new field enables provider developers to swap pieces of resident memory usage for the slight additional computation time of reconstituting the data when necessary.

Callers directly referencing the exported Schema field should switch to referencing the SchemaMap method, which returns the result of SchemaFunc or Schema in that preference order. To ensure internal usage was migrated to the new method, this change was performed by temporarily commenting out the Schema field itself with broken references in non-testing code migrated to the method. The Schema field is not marked as deprecated via Go documentation comment as this would introduce a major ecosystem burden to migrate with generally little benefit for most use cases.

The Resource type InternalValidate method has been updated to return an error if both Schema and SchemaFunc are defined.

Provider developers are encouraged to migrate resources to the terraform-plugin-framework, as it already behaves in a manner similar to SchemaFunc by nature of resource schema data being behind a method call, amongst many of the other benefits outlined at https://developer.hashicorp.com/terraform/plugin/framework-benefits.

Reference: #1217

This change introduces a new `SchemaFunc` field and `SchemaMap` method to the `Resource` type. Currently, the `Schema` field data of all `Resource` is held in memory for the lifecycle of the provider server, which is problematic for providers with many resources and/or larger schemas in resources. The new field enables provider developers to swap pieces of resident memory usage for the slight additional computation time of reconstituting the data when necessary.

Callers directly referencing the exported `Schema` field should switch to referencing the `SchemaMap` method, which returns the result of `SchemaFunc` or `Schema` in that preference order. To ensure internal usage was migrated to the new method, this change was performed by temporarily commenting out the `Schema` field itself with broken references in non-testing code migrated to the method. The `Schema` field is not marked as deprecated via Go documentation comment as this would introduce a major ecosystem burden to migrate with generally little benefit for most use cases.

The `Resource` type `InternalValidate` method has been updated to return an error if both `Schema` and `SchemaFunc` are defined.

Provider developers are encouraged to migrate resources to the terraform-plugin-framework, as it already behaves in a manner similar to `SchemaFunc` by nature of resource schema data being behind a method call, amongst many of the other benefits outlined at https://developer.hashicorp.com/terraform/plugin/framework-benefits.
@bflad bflad added the enhancement New feature or request label Jun 23, 2023
@bflad bflad added this to the v2.27.0 milestone Jun 23, 2023
@bflad bflad requested a review from a team as a code owner June 23, 2023 14:56
// The keys of this map are the names used in a practitioner configuration,
// such as the attribute or block name. The values describe the structure
// and type information of that attribute or block.
SchemaFunc func() map[string]*Schema
Copy link
Contributor

@ewbankkit ewbankkit Jun 23, 2023

Choose a reason for hiding this comment

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

Is it excessive to request a context.Context argument here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, maybe it is as I see that callers don't have a context.Context.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Usually I'd be all about it, but we would need to verify it can be properly passed from RPC logic all the way through to calling these functions. I'm curious about the expected need for it though? e.g. Is there a need to log anything in schema definitions?

Most provider code that I've run across with "schema functions" typically use function signatures without it. For some examples of what I mean:

So adding the context will then require logic updates in those to pass the upstream context through all downstream schema function calls.

If having a proper context available is important for a use case, I'd suggest migrating the resource to the terraform-plugin-framework instead, which does already thread the context through properly, rather than spending additional time/effort on updating sdk-based code.

Copy link
Contributor

Choose a reason for hiding this comment

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

No, I had no concrete use case in mind and there are other "Func"s that don't have a Context argument (e.g. schema.StateFunc), so please ignore my ramblings 😄.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I took a quick peek at what it might take to support context.Context properly through here and unfortunately the internals meander into a lot of various functions/methods without it, including quite a few exported methods that would require breaking changes. While it would generally be possible to create duplicate, context-aware counterparts, I think its a whole lot of lift.

Copy link
Contributor

@bendbennett bendbennett left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@ewbankkit
Copy link
Contributor

LGTM 🚀.

@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 Jul 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

helper/schema: Provide Functionality to Reduce Resident Memory Usage from Schemas
3 participants