Skip to content

Commit

Permalink
feat: make administrative request retries optional (#2476)
Browse files Browse the repository at this point in the history
* feat: make administrative request retries optional

Make retries of administrative requests that fail because the
administrative request limit has been exceeded optional. This allows
users to apply custom retries or other custom handling for these errors.

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
olavloite and gcf-owl-bot[bot] committed Jun 2, 2023
1 parent a49c872 commit ee6548c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
Expand Up @@ -993,13 +993,26 @@ public Builder setAutoThrottleAdministrativeRequests() {
return this;
}

/**
* Disables automatic retries of administrative requests that fail if the <a
* href="https://cloud.google.com/spanner/quotas#administrative_limits">https://cloud.google.com/spanner/quotas#administrative_limits</a>
* have been exceeded. You should disable these retries if you intend to handle these errors in
* your application.
*/
public Builder disableAdministrativeRequestRetries() {
this.retryAdministrativeRequestsSettings =
this.retryAdministrativeRequestsSettings.toBuilder().setMaxAttempts(1).build();
return this;
}

/**
* Sets the retry settings for retrying administrative requests when the quote of administrative
* requests per minute has been exceeded.
*/
Builder setRetryAdministrativeRequestsSettings(
RetrySettings retryAdministrativeRequestsSettings) {
this.retryAdministrativeRequestsSettings = retryAdministrativeRequestsSettings;
this.retryAdministrativeRequestsSettings =
Preconditions.checkNotNull(retryAdministrativeRequestsSettings);
return this;
}

Expand Down
Expand Up @@ -935,4 +935,31 @@ public void testRetryOperationOnAdminMethodQuotaPerMinutePerProjectExceeded() {
assertEquals(DB_ID, database.getId().getDatabase());
assertEquals(2, mockDatabaseAdmin.countRequestsOfType(GetDatabaseRequest.class));
}

@Test
public void testRetriesDisabledForOperationOnAdminMethodQuotaPerMinutePerProjectExceeded() {
ErrorInfo info =
ErrorInfo.newBuilder()
.putMetadata("quota_limit", "AdminMethodQuotaPerMinutePerProject")
.build();
Metadata.Key<ErrorInfo> key =
Metadata.Key.of(
info.getDescriptorForType().getFullName() + Metadata.BINARY_HEADER_SUFFIX,
ProtoLiteUtils.metadataMarshaller(info));
Metadata trailers = new Metadata();
trailers.put(key, info);
mockDatabaseAdmin.addException(
Status.RESOURCE_EXHAUSTED.withDescription("foo").asRuntimeException(trailers));
mockDatabaseAdmin.clearRequests();

Spanner spannerWithoutRetries =
spanner.getOptions().toBuilder().disableAdministrativeRequestRetries().build().getService();
AdminRequestsPerMinuteExceededException exception =
assertThrows(
AdminRequestsPerMinuteExceededException.class,
() -> spannerWithoutRetries.getDatabaseAdminClient().getDatabase(INSTANCE_ID, DB_ID));
assertEquals(ErrorCode.RESOURCE_EXHAUSTED, exception.getErrorCode());
// There should be only one request on the server, as the request was not retried.
assertEquals(1, mockDatabaseAdmin.countRequestsOfType(GetDatabaseRequest.class));
}
}

0 comments on commit ee6548c

Please sign in to comment.