|
65 | 65 | import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStub; |
66 | 66 | import com.google.cloud.spanner.admin.database.v1.stub.DatabaseAdminStubSettings; |
67 | 67 | import com.google.cloud.spanner.admin.database.v1.stub.GrpcDatabaseAdminCallableFactory; |
| 68 | +import com.google.cloud.spanner.admin.database.v1.stub.GrpcDatabaseAdminStub; |
68 | 69 | import com.google.cloud.spanner.admin.instance.v1.stub.GrpcInstanceAdminStub; |
69 | 70 | import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStub; |
70 | 71 | import com.google.cloud.spanner.admin.instance.v1.stub.InstanceAdminStubSettings; |
|
76 | 77 | import com.google.common.base.MoreObjects; |
77 | 78 | import com.google.common.base.Preconditions; |
78 | 79 | import com.google.common.collect.ImmutableList; |
79 | | -import com.google.common.collect.ImmutableSet; |
80 | 80 | import com.google.common.collect.ImmutableMap; |
| 81 | +import com.google.common.collect.ImmutableSet; |
81 | 82 | import com.google.common.util.concurrent.RateLimiter; |
82 | 83 | import com.google.common.util.concurrent.ThreadFactoryBuilder; |
83 | 84 | import com.google.iam.v1.GetIamPolicyRequest; |
@@ -450,33 +451,45 @@ public GapicSpannerRpc(final SpannerOptions options) { |
450 | 451 | .setCredentialsProvider(credentialsProvider) |
451 | 452 | .setStreamWatchdogProvider(watchdogProvider) |
452 | 453 | .build(); |
453 | | - GrpcStubCallableFactory factory = |
454 | | - new GrpcDatabaseAdminCallableFactory() { |
455 | | - @Override |
456 | | - public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable( |
457 | | - GrpcCallSettings<RequestT, ResponseT> grpcCallSettings, |
458 | | - UnaryCallSettings<RequestT, ResponseT> callSettings, |
459 | | - ClientContext clientContext) { |
460 | | - // Make GetOperation retry on RESOURCE_EXHAUSTED to prevent polling operations from |
461 | | - // failing with an Administrative requests limit exceeded error. |
462 | | - if (grpcCallSettings |
463 | | - .getMethodDescriptor() |
464 | | - .getFullMethodName() |
465 | | - .equals("google.longrunning.Operations/GetOperation")) { |
466 | | - Set<StatusCode.Code> codes = |
467 | | - ImmutableSet.<StatusCode.Code>builderWithExpectedSize( |
468 | | - callSettings.getRetryableCodes().size() + 1) |
469 | | - .addAll(callSettings.getRetryableCodes()) |
470 | | - .add(StatusCode.Code.RESOURCE_EXHAUSTED) |
471 | | - .build(); |
472 | | - callSettings = callSettings.toBuilder().setRetryableCodes(codes).build(); |
| 454 | + |
| 455 | + // Automatically retry RESOURCE_EXHAUSTED for GetOperation if auto-throttling of |
| 456 | + // administrative requests has been set. The GetOperation RPC is called repeatedly by gax |
| 457 | + // while polling long-running operations for their progress and can also cause these errors. |
| 458 | + // The default behavior is not to retry these errors, and this option should normally only be |
| 459 | + // enabled for (integration) testing. |
| 460 | + if (options.isAutoThrottleAdministrativeRequests()) { |
| 461 | + GrpcStubCallableFactory factory = |
| 462 | + new GrpcDatabaseAdminCallableFactory() { |
| 463 | + @Override |
| 464 | + public <RequestT, ResponseT> UnaryCallable<RequestT, ResponseT> createUnaryCallable( |
| 465 | + GrpcCallSettings<RequestT, ResponseT> grpcCallSettings, |
| 466 | + UnaryCallSettings<RequestT, ResponseT> callSettings, |
| 467 | + ClientContext clientContext) { |
| 468 | + // Make GetOperation retry on RESOURCE_EXHAUSTED to prevent polling operations from |
| 469 | + // failing with an Administrative requests limit exceeded error. |
| 470 | + if (grpcCallSettings |
| 471 | + .getMethodDescriptor() |
| 472 | + .getFullMethodName() |
| 473 | + .equals("google.longrunning.Operations/GetOperation")) { |
| 474 | + Set<StatusCode.Code> codes = |
| 475 | + ImmutableSet.<StatusCode.Code>builderWithExpectedSize( |
| 476 | + callSettings.getRetryableCodes().size() + 1) |
| 477 | + .addAll(callSettings.getRetryableCodes()) |
| 478 | + .add(StatusCode.Code.RESOURCE_EXHAUSTED) |
| 479 | + .build(); |
| 480 | + callSettings = callSettings.toBuilder().setRetryableCodes(codes).build(); |
| 481 | + } |
| 482 | + return super.createUnaryCallable(grpcCallSettings, callSettings, clientContext); |
473 | 483 | } |
474 | | - return super.createUnaryCallable(grpcCallSettings, callSettings, clientContext); |
475 | | - } |
476 | | - }; |
477 | | - this.databaseAdminStub = |
478 | | - new GrpcDatabaseAdminStubWithCustomCallableFactory( |
479 | | - databaseAdminStubSettings, ClientContext.create(databaseAdminStubSettings), factory); |
| 484 | + }; |
| 485 | + this.databaseAdminStub = |
| 486 | + new GrpcDatabaseAdminStubWithCustomCallableFactory( |
| 487 | + databaseAdminStubSettings, |
| 488 | + ClientContext.create(databaseAdminStubSettings), |
| 489 | + factory); |
| 490 | + } else { |
| 491 | + this.databaseAdminStub = GrpcDatabaseAdminStub.create(databaseAdminStubSettings); |
| 492 | + } |
480 | 493 |
|
481 | 494 | // Check whether the SPANNER_EMULATOR_HOST env var has been set, and if so, if the emulator is |
482 | 495 | // actually running. |
|
0 commit comments