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

feat: Add support for Managed Autoscaler #2624

Merged
merged 7 commits into from Oct 19, 2023

Conversation

claire921
Copy link
Contributor

@claire921 claire921 commented Sep 14, 2023

  • Add the ability to create / update an instance with autoscaling config
    • Note that now user can only specify one of the node_count, processing_units or autoscaling_config as the compute capacity for an instance.
  • Add the ability to see autoscaling config with an instance

@claire921 claire921 requested review from a team as code owners September 14, 2023 00:11
@product-auto-label product-auto-label bot added size: l Pull request size is large. api: spanner Issues related to the googleapis/java-spanner API. labels Sep 14, 2023
@generated-files-bot
Copy link

generated-files-bot bot commented Sep 14, 2023

Warning: This pull request is touching the following templated files:

  • google-cloud-spanner/src/test/java/com/google/cloud/spanner/admin/instance/v1/InstanceAdminClientTest.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/Instance.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/InstanceOrBuilder.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/java/com/google/spanner/admin/instance/v1/SpannerInstanceAdminProto.java
  • proto-google-cloud-spanner-admin-instance-v1/src/main/proto/google/spanner/admin/instance/v1/spanner_instance_admin.proto

@product-auto-label product-auto-label bot added size: xl Pull request size is extra large. and removed size: l Pull request size is large. labels Sep 19, 2023
@claire921 claire921 changed the title feat: add support for Managed Autoscaler feat: Add support for Managed Autoscaler Sep 19, 2023
if (info.getAutoscalingConfig() != null) {
return new InstanceField[] {DISPLAY_NAME, AUTOSCALING_CONFIG, LABELS};
} else if (info.getNodeCount() > 0) {
return new InstanceField[] {DISPLAY_NAME, AUTOSCALING_CONFIG, NODE_COUNT, LABELS};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does this array contain both NODE_COUNT and AUTOSCALING_CONFIG ? It should contain just NODE_COUNT ? Could you check if any unit tests broke here or this was a silent error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When you switch from an autoscaler instance to a non-autoscaler instance, the backend requires both the autoscaling_config and node_count field masks to make sure the intention is to clear the autoscaling_config and set a node_count.

LMK if there is a better alternative for this approach; otherwise I can add a comment for this to make it less confusing.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There are a few edge cases and open question here:

  1. when getAutoscalingConfig != null, we are updating just AUTOSCALING_CONFIG. Shouldn't we have checks to include NODE_COUNT and PROCESSING_UNITS (to be set to 0) ?
  2. If getNodeCount > 0, we are updating just NODE_COUNT. What if an instance already had PROCESSING_UNITS ? I assume the backend will throw a validation error. Similar question for the else condition.
  3. If we are not marking PROCESSING_UNITS or NODE_COUNT as 0 in the second check, then why are we explicitly marking AUTOSCALING_CONFIG as null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For #1, customers can only autoscaling_config once autoscaler is enabled. node_count and processing_units are output_only params. An instance can still have node_count and processing_units, it is just customers cannot modify them. This is consistent with CBT autoscaling API: https://screenshot.googleplex.com/6mi2r2QUKMfTk7x

For #2, this seems to be the logic before the autoscaler related changes. My understanding is that this method is to provide a default field mask when user did not specify one. I'm not sure why we did this in the first place -- as you pointed out, if an instance is specified with both nodes and processing units, this can be wrong. I'm following an existing pattern here.

For #3, if the autoscaling_config is not null, that means this is an autoscaler instance, and users should not specify processing_units or node_count as part of the field mask. If it is null, then the user intention will be to update a non-autoscaling instance.

@@ -193,9 +193,18 @@ public Operation fromProto(Operation proto) {
@Override
public OperationFuture<Instance, CreateInstanceMetadata> createInstance(InstanceInfo instance)
throws SpannerException {
boolean valid_capacity_with_autoscaling =
instance.getAutoscalingConfig() != null
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this validation just specific to createInstance RPC? What about other RPCs ? I am wondering if these validations are better suited when we invoke setAutoscalingConfig method than within RPC.

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, how are such validations supported in auto-generated languages (for ex - Golang) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this validation just specific to createInstance RPC? What about other RPCs ? I am wondering if these validations are better suited when we invoke setAutoscalingConfig method than within RPC.

When they updateInstance, they should also only specify one of the PU, nodes or autoscaling config.

The check was here before so I modified it to take autoscaling config into account, but I can move it to another place if that makes more sense.

Also, how are such validations supported in auto-generated languages (for ex - Golang) ?

So the backend will do the validation check any way, so if it is auto-generated languages, it will be rejected by the backend.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sure, let's get rid of the validation all together and rely on the backend validation. Some simpler validation on primitive types can be considered to be moved to the protos. This in general is preferred since we are gradually moving in a direction on how we can simplify our handwritten clients (similar to our auto-generated clients). So, this would be a step in that direction.

@snippet-bot
Copy link

snippet-bot bot commented Oct 12, 2023

No region tags are edited in this PR.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@arpan14 arpan14 closed this Oct 13, 2023
@product-auto-label product-auto-label bot added size: u Pull request is empty. and removed size: xl Pull request size is extra large. labels Oct 13, 2023
@arpan14 arpan14 reopened this Oct 13, 2023
@product-auto-label product-auto-label bot added size: l Pull request size is large. and removed size: u Pull request is empty. labels Oct 13, 2023
import com.google.cloud.spanner.IntegrationTestEnv;
import com.google.cloud.spanner.Options;
import com.google.cloud.spanner.ParallelIntegrationTest;
import com.google.cloud.spanner.*;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Revert this change and bring back the full imports. I think this could be an IDE setting which might be automatically opimizing the imports. You may need to switch off this IDE setting. Reference - https://www.jetbrains.com/help/idea/creating-and-optimizing-imports.html#optimize-imports

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted.

if (info.getAutoscalingConfig() != null) {
return new InstanceField[] {DISPLAY_NAME, AUTOSCALING_CONFIG, LABELS};
} else if (info.getNodeCount() > 0) {
return new InstanceField[] {DISPLAY_NAME, AUTOSCALING_CONFIG, NODE_COUNT, LABELS};
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are a few edge cases and open question here:

  1. when getAutoscalingConfig != null, we are updating just AUTOSCALING_CONFIG. Shouldn't we have checks to include NODE_COUNT and PROCESSING_UNITS (to be set to 0) ?
  2. If getNodeCount > 0, we are updating just NODE_COUNT. What if an instance already had PROCESSING_UNITS ? I assume the backend will throw a validation error. Similar question for the else condition.
  3. If we are not marking PROCESSING_UNITS or NODE_COUNT as 0 in the second check, then why are we explicitly marking AUTOSCALING_CONFIG as null?

.build()))
.thenReturn(rawOperationFuture);
InstanceInfo instanceInfo =
InstanceInfo.newBuilder(InstanceId.of(INSTANCE_NAME))
.setInstanceConfigId(InstanceConfigId.of(CONFIG_NAME))
.setNodeCount(3)
.setProcessingUnits(3000)
.setAutoscalingConfig(getAutoscalingConfigProto())
.build();
OperationFuture<Instance, UpdateInstanceMetadata> operationWithFieldMask =
client.updateInstance(instanceInfo);
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • Can we add more assertions on what we expect the node count, processing unit and autoscaling config to contain, similar to how we are asserting INSTANCE_NAME ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same above.

OperationFuture<Instance, UpdateInstanceMetadata> operationWithFieldMask =
client.updateInstance(instanceInfo);
assertTrue(operationWithFieldMask.isDone());
assertEquals(INSTANCE_NAME, operationWithFieldMask.get().getId().getName());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add more assertions on fields being updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same above

OperationFuture<Instance, UpdateInstanceMetadata> operation =
client.updateInstance(instanceInfo);
assertTrue(operation.isDone());
assertEquals(INSTANCE_NAME, operation.get().getId().getName());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add few more assertions on value of nodecount, processing units and autoscaling config. Applicable at other tests as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The assertions are probably not needed, because we mock the RPC to return an instance only with processing_units: https://screenshot.googleplex.com/7fF5jTJZ8hbQ2nn. So if we add assertions, the assertions will only be to test the mocking of the RPC, instead of the actual code.

@arpan14 arpan14 added the owlbot:run Add this label to trigger the Owlbot post processor. label Oct 19, 2023
@gcf-owl-bot gcf-owl-bot bot removed the owlbot:run Add this label to trigger the Owlbot post processor. label Oct 19, 2023
@arpan14 arpan14 added the automerge Merge the pull request once unit tests and other checks pass. label Oct 19, 2023
@arpan14 arpan14 added kokoro:force-run Add this label to force Kokoro to re-run the tests. kokoro:run Add this label to force Kokoro to re-run the tests. labels Oct 19, 2023
@yoshi-kokoro yoshi-kokoro removed kokoro:run Add this label to force Kokoro to re-run the tests. kokoro:force-run Add this label to force Kokoro to re-run the tests. labels Oct 19, 2023
@gcf-merge-on-green gcf-merge-on-green bot merged commit e5e6923 into googleapis:main Oct 19, 2023
22 checks passed
@gcf-merge-on-green gcf-merge-on-green bot removed the automerge Merge the pull request once unit tests and other checks pass. label Oct 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/java-spanner API. size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants