Search in sources :

Example 1 with MutateRowsResponse

use of com.google.bigtable.v2.MutateRowsResponse in project java-bigtable by googleapis.

the class EnhancedBigtableStub method createMutateRowsBaseCallable.

/**
 * Internal helper to create the base MutateRows callable chain. The chain is responsible for
 * retrying individual entry in case of error.
 *
 * <p>NOTE: the caller is responsible for adding tracing & metrics.
 *
 * @see MutateRowsRetryingCallable for more details
 */
private UnaryCallable<MutateRowsRequest, Void> createMutateRowsBaseCallable() {
    ServerStreamingCallable<MutateRowsRequest, MutateRowsResponse> base = GrpcRawCallableFactory.createServerStreamingCallable(GrpcCallSettings.<MutateRowsRequest, MutateRowsResponse>newBuilder().setMethodDescriptor(BigtableGrpc.getMutateRowsMethod()).setParamsExtractor(new RequestParamsExtractor<MutateRowsRequest>() {

        @Override
        public Map<String, String> extract(MutateRowsRequest mutateRowsRequest) {
            return ImmutableMap.of("table_name", mutateRowsRequest.getTableName(), "app_profile_id", mutateRowsRequest.getAppProfileId());
        }
    }).build(), settings.bulkMutateRowsSettings().getRetryableCodes());
    ServerStreamingCallable<MutateRowsRequest, MutateRowsResponse> withStatsHeaders = new StatsHeadersServerStreamingCallable<>(base);
    RetryAlgorithm<Void> retryAlgorithm = new RetryAlgorithm<>(new ApiResultRetryAlgorithm<Void>(), new ExponentialRetryAlgorithm(settings.bulkMutateRowsSettings().getRetrySettings(), clientContext.getClock()));
    RetryingExecutorWithContext<Void> retryingExecutor = new ScheduledRetryingExecutor<>(retryAlgorithm, clientContext.getExecutor());
    return new MutateRowsRetryingCallable(clientContext.getDefaultCallContext(), withStatsHeaders, retryingExecutor, settings.bulkMutateRowsSettings().getRetryableCodes());
}
Also used : RetryAlgorithm(com.google.api.gax.retrying.RetryAlgorithm) ExponentialRetryAlgorithm(com.google.api.gax.retrying.ExponentialRetryAlgorithm) ApiResultRetryAlgorithm(com.google.cloud.bigtable.gaxx.retrying.ApiResultRetryAlgorithm) ExponentialRetryAlgorithm(com.google.api.gax.retrying.ExponentialRetryAlgorithm) StatsHeadersServerStreamingCallable(com.google.cloud.bigtable.data.v2.stub.metrics.StatsHeadersServerStreamingCallable) ScheduledRetryingExecutor(com.google.api.gax.retrying.ScheduledRetryingExecutor) MutateRowsResponse(com.google.bigtable.v2.MutateRowsResponse) MutateRowsRequest(com.google.bigtable.v2.MutateRowsRequest) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) MutateRowsRetryingCallable(com.google.cloud.bigtable.data.v2.stub.mutaterows.MutateRowsRetryingCallable)

Example 2 with MutateRowsResponse

use of com.google.bigtable.v2.MutateRowsResponse in project java-bigtable by googleapis.

the class MetricsTracerTest method testBatchMutateRowsThrottledTime.

@Test
public void testBatchMutateRowsThrottledTime() throws Exception {
    FlowController flowController = Mockito.mock(FlowController.class);
    BatchingDescriptor batchingDescriptor = Mockito.mock(MutateRowsBatchingDescriptor.class);
    // Mock throttling
    final long throttled = 50;
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            Thread.sleep(throttled);
            return null;
        }
    }).when(flowController).reserve(any(Long.class), any(Long.class));
    when(flowController.getMaxElementCountLimit()).thenReturn(null);
    when(flowController.getMaxRequestBytesLimit()).thenReturn(null);
    when(batchingDescriptor.countBytes(any())).thenReturn(1l);
    when(batchingDescriptor.newRequestBuilder(any())).thenCallRealMethod();
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocation) {
            @SuppressWarnings("unchecked") StreamObserver<MutateRowsResponse> observer = (StreamObserver<MutateRowsResponse>) invocation.getArguments()[1];
            observer.onNext(MutateRowsResponse.getDefaultInstance());
            observer.onCompleted();
            return null;
        }
    }).when(mockService).mutateRows(any(MutateRowsRequest.class), any());
    ApiCallContext defaultContext = GrpcCallContext.createDefault();
    Batcher batcher = new BatcherImpl(batchingDescriptor, stub.bulkMutateRowsCallable().withDefaultCallContext(defaultContext), BulkMutation.create(TABLE_ID), settings.getStubSettings().bulkMutateRowsSettings().getBatchingSettings(), Executors.newSingleThreadScheduledExecutor(), flowController, defaultContext);
    batcher.add(RowMutationEntry.create("key"));
    batcher.sendOutstanding();
    Thread.sleep(100);
    long throttledTimeMetric = StatsTestUtils.getAggregationValueAsLong(localStats, RpcViewConstants.BIGTABLE_BATCH_THROTTLED_TIME_VIEW, ImmutableMap.of(RpcMeasureConstants.BIGTABLE_OP, TagValue.create("Bigtable.MutateRows")), PROJECT_ID, INSTANCE_ID, APP_PROFILE_ID);
    assertThat(throttledTimeMetric).isAtLeast(throttled);
}
Also used : StreamObserver(io.grpc.stub.StreamObserver) MutateRowsBatchingDescriptor(com.google.cloud.bigtable.data.v2.stub.mutaterows.MutateRowsBatchingDescriptor) BatchingDescriptor(com.google.api.gax.batching.BatchingDescriptor) ApiCallContext(com.google.api.gax.rpc.ApiCallContext) BatcherImpl(com.google.api.gax.batching.BatcherImpl) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) MutateRowsResponse(com.google.bigtable.v2.MutateRowsResponse) MutateRowsRequest(com.google.bigtable.v2.MutateRowsRequest) Batcher(com.google.api.gax.batching.Batcher) InvocationOnMock(org.mockito.invocation.InvocationOnMock) FlowController(com.google.api.gax.batching.FlowController) Test(org.junit.Test)

Example 3 with MutateRowsResponse

use of com.google.bigtable.v2.MutateRowsResponse in project java-bigtable by googleapis.

the class MutateRowsAttemptCallableTest method rpcPermanentError.

@Test
public void rpcPermanentError() {
    // Setup the request & response
    MutateRowsRequest request = MutateRowsRequest.newBuilder().addEntries(Entry.getDefaultInstance()).addEntries(Entry.getDefaultInstance()).build();
    final UnavailableException rpcError = new UnavailableException("fake error", null, GrpcStatusCode.of(io.grpc.Status.Code.INVALID_ARGUMENT), false);
    UnaryCallable<MutateRowsRequest, List<MutateRowsResponse>> innerCallable = new UnaryCallable<MutateRowsRequest, List<MutateRowsResponse>>() {

        @Override
        public ApiFuture<List<MutateRowsResponse>> futureCall(MutateRowsRequest request, ApiCallContext context) {
            return ApiFutures.immediateFailedFuture(rpcError);
        }
    };
    // Make the call
    MutateRowsAttemptCallable attemptCallable = new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
    attemptCallable.setExternalFuture(parentFuture);
    attemptCallable.call();
    // Overall expectations: retryable error
    Throwable actualError = null;
    try {
        parentFuture.attemptFuture.get();
    } catch (Throwable t) {
        actualError = t.getCause();
    }
    assertThat(actualError).isInstanceOf(MutateRowsException.class);
    assertThat(((MutateRowsException) actualError).isRetryable()).isFalse();
    // Entry expectations: both entries failed with an error whose cause is the rpc error
    @SuppressWarnings("ConstantConditions") List<FailedMutation> failedMutations = ((MutateRowsException) actualError).getFailedMutations();
    assertThat(failedMutations).hasSize(2);
    assertThat(failedMutations.get(0).getIndex()).isEqualTo(0);
    assertThat(failedMutations.get(0).getError().isRetryable()).isFalse();
    assertThat(failedMutations.get(0).getError().getCause()).isEqualTo(rpcError);
    assertThat(failedMutations.get(1).getIndex()).isEqualTo(1);
    assertThat(failedMutations.get(1).getError().isRetryable()).isFalse();
    assertThat(failedMutations.get(1).getError().getCause()).isEqualTo(rpcError);
}
Also used : UnaryCallable(com.google.api.gax.rpc.UnaryCallable) UnavailableException(com.google.api.gax.rpc.UnavailableException) ApiCallContext(com.google.api.gax.rpc.ApiCallContext) FailedMutation(com.google.cloud.bigtable.data.v2.models.MutateRowsException.FailedMutation) MutateRowsResponse(com.google.bigtable.v2.MutateRowsResponse) MutateRowsException(com.google.cloud.bigtable.data.v2.models.MutateRowsException) MutateRowsRequest(com.google.bigtable.v2.MutateRowsRequest) List(java.util.List) Test(org.junit.Test)

Example 4 with MutateRowsResponse

use of com.google.bigtable.v2.MutateRowsResponse in project java-bigtable by googleapis.

the class MutateRowsAttemptCallableTest method rpcRetryableError.

@Test
public void rpcRetryableError() {
    // Setup the request & response
    MutateRowsRequest request = MutateRowsRequest.newBuilder().addEntries(Entry.getDefaultInstance()).addEntries(Entry.getDefaultInstance()).build();
    final UnavailableException rpcError = new UnavailableException("fake error", null, GrpcStatusCode.of(io.grpc.Status.Code.UNAVAILABLE), true);
    UnaryCallable<MutateRowsRequest, List<MutateRowsResponse>> innerCallable = new UnaryCallable<MutateRowsRequest, List<MutateRowsResponse>>() {

        @Override
        public ApiFuture<List<MutateRowsResponse>> futureCall(MutateRowsRequest request, ApiCallContext context) {
            return ApiFutures.immediateFailedFuture(rpcError);
        }
    };
    // Make the call
    MutateRowsAttemptCallable attemptCallable = new MutateRowsAttemptCallable(innerCallable, request, callContext, retryCodes);
    attemptCallable.setExternalFuture(parentFuture);
    attemptCallable.call();
    // Overall expectations: retryable error
    Throwable actualError = null;
    try {
        parentFuture.attemptFuture.get();
    } catch (Throwable t) {
        actualError = t.getCause();
    }
    assertThat(actualError).isInstanceOf(MutateRowsException.class);
    assertThat(((MutateRowsException) actualError).isRetryable()).isTrue();
    // Entry expectations: both entries failed with an error whose cause is the rpc error
    @SuppressWarnings("ConstantConditions") List<FailedMutation> failedMutations = ((MutateRowsException) actualError).getFailedMutations();
    assertThat(failedMutations).hasSize(2);
    assertThat(failedMutations.get(0).getIndex()).isEqualTo(0);
    assertThat(failedMutations.get(0).getError().isRetryable()).isTrue();
    assertThat(failedMutations.get(0).getError().getCause()).isEqualTo(rpcError);
    assertThat(failedMutations.get(1).getIndex()).isEqualTo(1);
    assertThat(failedMutations.get(1).getError().isRetryable()).isTrue();
    assertThat(failedMutations.get(1).getError().getCause()).isEqualTo(rpcError);
}
Also used : UnaryCallable(com.google.api.gax.rpc.UnaryCallable) UnavailableException(com.google.api.gax.rpc.UnavailableException) ApiCallContext(com.google.api.gax.rpc.ApiCallContext) FailedMutation(com.google.cloud.bigtable.data.v2.models.MutateRowsException.FailedMutation) MutateRowsResponse(com.google.bigtable.v2.MutateRowsResponse) MutateRowsException(com.google.cloud.bigtable.data.v2.models.MutateRowsException) MutateRowsRequest(com.google.bigtable.v2.MutateRowsRequest) List(java.util.List) Test(org.junit.Test)

Example 5 with MutateRowsResponse

use of com.google.bigtable.v2.MutateRowsResponse in project java-bigtable by googleapis.

the class MutateRowsAttemptCallable method handleAttemptSuccess.

/**
 * Handle entry level failures. All new response entries are inspected for failure. If any
 * transient failures are found, their corresponding mutations are scheduled for the next RPC. The
 * caller is notified of both new found errors and pre-existing permanent errors in the thrown
 * {@link MutateRowsException}. If no errors exist, then the attempt future is successfully
 * completed.
 */
private void handleAttemptSuccess(List<MutateRowsResponse> responses) {
    List<FailedMutation> allFailures = Lists.newArrayList(permanentFailures);
    MutateRowsRequest lastRequest = currentRequest;
    Builder builder = lastRequest.toBuilder().clearEntries();
    List<Integer> newOriginalIndexes = Lists.newArrayList();
    for (MutateRowsResponse response : responses) {
        for (Entry entry : response.getEntriesList()) {
            if (entry.getStatus().getCode() == Code.OK_VALUE) {
                continue;
            }
            int origIndex = getOriginalIndex((int) entry.getIndex());
            FailedMutation failedMutation = FailedMutation.create(origIndex, createEntryError(entry.getStatus()));
            allFailures.add(failedMutation);
            if (!failedMutation.getError().isRetryable()) {
                permanentFailures.add(failedMutation);
            } else {
                // Schedule the mutation entry for the next RPC by adding it to the request builder and
                // recording it's original index
                newOriginalIndexes.add(origIndex);
                builder.addEntries(lastRequest.getEntries((int) entry.getIndex()));
            }
        }
    }
    currentRequest = builder.build();
    originalIndexes = newOriginalIndexes;
    if (!allFailures.isEmpty()) {
        boolean isRetryable = builder.getEntriesCount() > 0;
        throw new MutateRowsException(null, allFailures, isRetryable);
    }
}
Also used : Entry(com.google.bigtable.v2.MutateRowsResponse.Entry) MutateRowsResponse(com.google.bigtable.v2.MutateRowsResponse) MutateRowsException(com.google.cloud.bigtable.data.v2.models.MutateRowsException) MutateRowsRequest(com.google.bigtable.v2.MutateRowsRequest) Builder(com.google.bigtable.v2.MutateRowsRequest.Builder) FailedMutation(com.google.cloud.bigtable.data.v2.models.MutateRowsException.FailedMutation)

Aggregations

MutateRowsRequest (com.google.bigtable.v2.MutateRowsRequest)5 MutateRowsResponse (com.google.bigtable.v2.MutateRowsResponse)5 ApiCallContext (com.google.api.gax.rpc.ApiCallContext)3 MutateRowsException (com.google.cloud.bigtable.data.v2.models.MutateRowsException)3 FailedMutation (com.google.cloud.bigtable.data.v2.models.MutateRowsException.FailedMutation)3 Test (org.junit.Test)3 UnaryCallable (com.google.api.gax.rpc.UnaryCallable)2 UnavailableException (com.google.api.gax.rpc.UnavailableException)2 List (java.util.List)2 Batcher (com.google.api.gax.batching.Batcher)1 BatcherImpl (com.google.api.gax.batching.BatcherImpl)1 BatchingDescriptor (com.google.api.gax.batching.BatchingDescriptor)1 FlowController (com.google.api.gax.batching.FlowController)1 ExponentialRetryAlgorithm (com.google.api.gax.retrying.ExponentialRetryAlgorithm)1 RetryAlgorithm (com.google.api.gax.retrying.RetryAlgorithm)1 ScheduledRetryingExecutor (com.google.api.gax.retrying.ScheduledRetryingExecutor)1 Builder (com.google.bigtable.v2.MutateRowsRequest.Builder)1 Entry (com.google.bigtable.v2.MutateRowsResponse.Entry)1 StatsHeadersServerStreamingCallable (com.google.cloud.bigtable.data.v2.stub.metrics.StatsHeadersServerStreamingCallable)1 MutateRowsBatchingDescriptor (com.google.cloud.bigtable.data.v2.stub.mutaterows.MutateRowsBatchingDescriptor)1