Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.

Commit 83407d9

Browse files
committed
fix
Change-Id: I572ff9eb1569f83a87ad67c59fbf5f023ef45a4c
1 parent c6723a4 commit 83407d9

8 files changed

Lines changed: 71 additions & 178 deletions

File tree

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/LargeRowException.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,27 @@
1616
package com.google.cloud.bigtable.data.v2.models;
1717

1818
import com.google.api.core.InternalApi;
19+
import com.google.api.gax.grpc.GrpcStatusCode;
1920
import com.google.api.gax.rpc.ApiException;
20-
import com.google.api.gax.rpc.StatusCode;
2121
import com.google.protobuf.ByteString;
22+
import io.grpc.Status;
2223
import java.util.List;
2324
import javax.annotation.Nonnull;
24-
import javax.annotation.Nullable;
2525

26-
/** Thrown by the ReadRows when at least one row was too large to be read. */
26+
/** Exception that wraps all the large row keys encountered in a ReadRows request. */
2727
public final class LargeRowException extends ApiException {
2828
private final List<ByteString> largeRowKeys;
2929

30-
/**
31-
* This constructor is considered an internal implementation detail and not meant to be used by
32-
* applications.
33-
*/
3430
@InternalApi
35-
public LargeRowException(
36-
@Nullable Throwable cause,
37-
@Nonnull StatusCode statusCode,
38-
boolean retryable,
39-
@Nonnull List<ByteString> largeRowKeys) {
40-
super(cause, statusCode, retryable);
31+
public LargeRowException(@Nonnull List<ByteString> largeRowKeys) {
32+
super(
33+
"Encountered large row keys",
34+
null,
35+
GrpcStatusCode.of(Status.Code.FAILED_PRECONDITION),
36+
false);
4137
this.largeRowKeys = largeRowKeys;
4238
}
4339

44-
@Override
45-
public String getMessage() {
46-
return "Large rows encountered: " + largeRowKeys;
47-
}
48-
4940
/** Retrieve the keys of the rows that were too large to be read. */
5041
@Nonnull
5142
public List<ByteString> getLargeRowKeys() {

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,10 @@ public <ReqT, RowT> ServerStreamingCallable<Query, RowT> createSkipLargeRowsCall
451451
// ReadRowsRequest -> ReadRowsResponse callable).
452452
// We override the resumption strategy to use LargeReadRowsResumptionStrategy here (which skips
453453
// the large rows) instead of ReadRowResumptionStrategy
454-
LargeReadRowsResumptionStrategy<RowT> strategy =
455-
new LargeReadRowsResumptionStrategy<>(rowAdapter, failOnLargeRows);
456454
ServerStreamingCallSettings<ReadRowsRequest, RowT> innerSettings =
457455
ServerStreamingCallSettings.<ReadRowsRequest, RowT>newBuilder()
458-
.setResumptionStrategy(strategy)
456+
.setResumptionStrategy(
457+
new LargeReadRowsResumptionStrategy<>(rowAdapter, failOnLargeRows))
459458
.setRetryableCodes(readRowsSettings.getRetryableCodes())
460459
.setRetrySettings(readRowsSettings.getRetrySettings())
461460
.setIdleTimeout(readRowsSettings.getIdleTimeout())

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ private Builder(EnhancedBigtableStubSettings settings) {
683683
jwtAudience = settings.jwtAudience;
684684
this.directPathConfig = settings.getDirectPathConfig();
685685
sessionsEnabled = settings.sessionsEnabled;
686+
failOnLargeRows = settings.failOnLargeRows;
686687

687688
this.perOpSettings = new ClientOperationSettings.Builder(settings.perOpSettings);
688689

@@ -1072,6 +1073,7 @@ public String toString() {
10721073
.add("jwtAudience", jwtAudience)
10731074
.add("directPathConfig", getDirectPathConfig().toString())
10741075
.add("sessionsEnabled", sessionsEnabled)
1076+
.add("failOnLargeRows", failOnLargeRows)
10751077
.add("parent", super.toString())
10761078
.toString();
10771079
}

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/readrows/LargeReadRowsResumptionStrategy.java

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,12 @@ public class LargeReadRowsResumptionStrategy<RowT>
6060
// row-keys
6161
private RowSet previousFailedRequestRowset = null;
6262

63-
private final List<ByteString> encounteredLargeRowKeys;
63+
private final List<ByteString> largeRowKeys = new ArrayList<>();
6464
private final boolean failOnLargeRows;
6565

6666
public LargeReadRowsResumptionStrategy(RowAdapter<RowT> rowAdapter, boolean failOnLargeRows) {
67-
this(rowAdapter, failOnLargeRows, new ArrayList<ByteString>());
68-
}
69-
70-
private LargeReadRowsResumptionStrategy(
71-
RowAdapter<RowT> rowAdapter,
72-
boolean failOnLargeRows,
73-
List<ByteString> encounteredLargeRowKeys) {
7467
this.rowAdapter = rowAdapter;
7568
this.failOnLargeRows = failOnLargeRows;
76-
this.encounteredLargeRowKeys = encounteredLargeRowKeys;
77-
}
78-
79-
public List<ByteString> getEncounteredLargeRowKeys() {
80-
return encounteredLargeRowKeys;
8169
}
8270

8371
@Override
@@ -87,8 +75,7 @@ public boolean canResume() {
8775

8876
@Override
8977
public StreamResumptionStrategy<ReadRowsRequest, RowT> createNew() {
90-
return new LargeReadRowsResumptionStrategy<>(
91-
rowAdapter, failOnLargeRows, encounteredLargeRowKeys);
78+
return new LargeReadRowsResumptionStrategy<>(rowAdapter, failOnLargeRows);
9279
}
9380

9481
@Override
@@ -113,24 +100,26 @@ public Throwable processError(Throwable throwable) {
113100
this.largeRowKey = rowKeyExtracted;
114101
numProcessed = numProcessed + 1;
115102
if (failOnLargeRows) {
116-
encounteredLargeRowKeys.add(rowKeyExtracted);
103+
largeRowKeys.add(rowKeyExtracted);
117104
} else {
118105
LOGGER.warning("skipping large row " + rowKeyExtracted);
119106
}
120107
}
121108
return throwable;
122109
}
123110

111+
public List<ByteString> getLargeRowKeys() {
112+
return largeRowKeys;
113+
}
114+
124115
private ByteString extractLargeRowKey(Throwable t) {
125-
if (t instanceof ApiException) {
126-
ApiException ae = (ApiException) t;
127-
if (ae.getReason() != null && ae.getReason().equals("LargeRowReadError")) {
128-
String rowKey = ae.getMetadata().get("rowKeyBase64Encoded");
129-
if (rowKey != null) {
130-
byte[] decodedBytes = Base64.getDecoder().decode(rowKey);
131-
return ByteString.copyFrom(decodedBytes);
132-
}
133-
}
116+
if (t instanceof ApiException
117+
&& ((ApiException) t).getReason() != null
118+
&& ((ApiException) t).getReason().equals("LargeRowReadError")) {
119+
String rowKey = ((ApiException) t).getMetadata().get("rowKeyBase64Encoded");
120+
121+
byte[] decodedBytes = Base64.getDecoder().decode(rowKey);
122+
return ByteString.copyFrom(decodedBytes);
134123
}
135124
return null;
136125
}

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/LargeRowServerStreamingAttemptCallable.java

Lines changed: 0 additions & 78 deletions
This file was deleted.

google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/gaxx/retrying/RetryingLargeRowServerStreamingCallable.java

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,44 +20,34 @@
2020
import com.google.api.core.ApiFutureCallback;
2121
import com.google.api.core.ApiFutures;
2222
import com.google.api.core.InternalApi;
23-
import com.google.api.gax.grpc.GrpcStatusCode;
2423
import com.google.api.gax.retrying.RetryingFuture;
2524
import com.google.api.gax.retrying.ScheduledRetryingExecutor;
2625
import com.google.api.gax.retrying.ServerStreamingAttemptException;
2726
import com.google.api.gax.rpc.ApiCallContext;
28-
import com.google.api.gax.rpc.ApiException;
2927
import com.google.api.gax.rpc.ResponseObserver;
3028
import com.google.api.gax.rpc.ServerStreamingCallable;
31-
import com.google.api.gax.rpc.StatusCode;
3229
import com.google.bigtable.v2.ReadRowsRequest;
3330
import com.google.cloud.bigtable.data.v2.models.LargeRowException;
3431
import com.google.cloud.bigtable.data.v2.stub.readrows.LargeReadRowsResumptionStrategy;
3532
import com.google.protobuf.ByteString;
36-
import io.grpc.Status;
37-
import io.grpc.StatusRuntimeException;
3833
import java.util.List;
3934

40-
/**
41-
* A ServerStreamingCallable that implements resumable retries for large rows.
42-
*
43-
* <p>This class is a specialized version of {@link RetryingServerStreamingCallable} that uses
44-
* {@link LargeRowServerStreamingAttemptCallable} and {@link LargeReadRowsResumptionStrategy}.
45-
*/
35+
/** A ServerStreamingCallable that throws large row keys at the end of the stream. */
4636
@InternalApi
4737
public final class RetryingLargeRowServerStreamingCallable<ResponseT>
4838
extends ServerStreamingCallable<ReadRowsRequest, ResponseT> {
4939

5040
private final ServerStreamingCallable<ReadRowsRequest, ResponseT> innerCallable;
5141
private final ScheduledRetryingExecutor<Void> executor;
52-
private final LargeReadRowsResumptionStrategy<ResponseT> resumptionStrategyPrototype;
42+
private final LargeReadRowsResumptionStrategy<ResponseT> resumptionStrategy;
5343

5444
public RetryingLargeRowServerStreamingCallable(
5545
ServerStreamingCallable<ReadRowsRequest, ResponseT> innerCallable,
5646
ScheduledRetryingExecutor<Void> executor,
57-
LargeReadRowsResumptionStrategy<ResponseT> resumptionStrategyPrototype) {
47+
LargeReadRowsResumptionStrategy<ResponseT> resumptionStrategy) {
5848
this.innerCallable = innerCallable;
5949
this.executor = executor;
60-
this.resumptionStrategyPrototype = resumptionStrategyPrototype;
50+
this.resumptionStrategy = resumptionStrategy;
6151
}
6252

6353
@Override
@@ -66,13 +56,12 @@ public void call(
6656
final ResponseObserver<ResponseT> responseObserver,
6757
ApiCallContext context) {
6858

69-
LargeRowServerStreamingAttemptCallable<ResponseT> attemptCallable =
70-
new LargeRowServerStreamingAttemptCallable<>(
71-
innerCallable,
72-
(LargeReadRowsResumptionStrategy<ResponseT>) resumptionStrategyPrototype.createNew(),
73-
request,
74-
context,
75-
responseObserver);
59+
final LargeReadRowsResumptionStrategy<ResponseT> strategy =
60+
(LargeReadRowsResumptionStrategy<ResponseT>) resumptionStrategy.createNew();
61+
62+
ServerStreamingAttemptCallable<ReadRowsRequest, ResponseT> attemptCallable =
63+
new ServerStreamingAttemptCallable<>(
64+
innerCallable, strategy, request, context, responseObserver);
7665

7766
RetryingFuture<Void> retryingFuture = executor.createFuture(attemptCallable, context);
7867
attemptCallable.setExternalFuture(retryingFuture);
@@ -88,35 +77,18 @@ public void onFailure(Throwable throwable) {
8877
if (throwable instanceof ServerStreamingAttemptException) {
8978
throwable = throwable.getCause();
9079
}
91-
List<ByteString> encounteredKeys =
92-
resumptionStrategyPrototype.getEncounteredLargeRowKeys();
80+
List<ByteString> encounteredKeys = strategy.getLargeRowKeys();
9381
if (!encounteredKeys.isEmpty()) {
94-
StatusCode statusCode = GrpcStatusCode.of(Status.Code.FAILED_PRECONDITION);
95-
boolean isRetryable = false;
96-
if (throwable instanceof ApiException) {
97-
statusCode = ((ApiException) throwable).getStatusCode();
98-
isRetryable = ((ApiException) throwable).isRetryable();
99-
} else if (throwable instanceof StatusRuntimeException) {
100-
statusCode =
101-
GrpcStatusCode.of(((StatusRuntimeException) throwable).getStatus().getCode());
102-
}
103-
throwable =
104-
new LargeRowException(throwable, statusCode, isRetryable, encounteredKeys);
82+
throwable.addSuppressed(new LargeRowException(encounteredKeys));
10583
}
10684
responseObserver.onError(throwable);
10785
}
10886

10987
@Override
11088
public void onSuccess(Void ignored) {
111-
List<ByteString> encounteredKeys =
112-
resumptionStrategyPrototype.getEncounteredLargeRowKeys();
89+
List<ByteString> encounteredKeys = strategy.getLargeRowKeys();
11390
if (!encounteredKeys.isEmpty()) {
114-
responseObserver.onError(
115-
new LargeRowException(
116-
null,
117-
GrpcStatusCode.of(Status.Code.FAILED_PRECONDITION),
118-
false,
119-
encounteredKeys));
91+
responseObserver.onError(new LargeRowException(encounteredKeys));
12092
} else {
12193
responseObserver.onComplete();
12294
}

0 commit comments

Comments
 (0)