102102import com .google .cloud .bigtable .data .v2 .stub .metrics .StatsHeadersUnaryCallable ;
103103import com .google .cloud .bigtable .data .v2 .stub .metrics .TracedBatcherUnaryCallable ;
104104import com .google .cloud .bigtable .data .v2 .stub .mutaterows .BulkMutateRowsUserFacingCallable ;
105+ import com .google .cloud .bigtable .data .v2 .stub .mutaterows .MutateRowsAttemptResult ;
105106import com .google .cloud .bigtable .data .v2 .stub .mutaterows .MutateRowsBatchingDescriptor ;
107+ import com .google .cloud .bigtable .data .v2 .stub .mutaterows .MutateRowsPartialErrorRetryAlgorithm ;
106108import com .google .cloud .bigtable .data .v2 .stub .mutaterows .MutateRowsRetryingCallable ;
107109import com .google .cloud .bigtable .data .v2 .stub .readrows .FilterMarkerRowsCallable ;
108110import com .google .cloud .bigtable .data .v2 .stub .readrows .ReadRowsBatchingDescriptor ;
@@ -165,7 +167,8 @@ public class EnhancedBigtableStub implements AutoCloseable {
165167 private final UnaryCallable <Query , List <Row >> bulkReadRowsCallable ;
166168 private final UnaryCallable <String , List <KeyOffset >> sampleRowKeysCallable ;
167169 private final UnaryCallable <RowMutation , Void > mutateRowCallable ;
168- private final UnaryCallable <BulkMutation , Void > bulkMutateRowsCallable ;
170+ private final UnaryCallable <BulkMutation , MutateRowsAttemptResult > bulkMutateRowsCallable ;
171+ private final UnaryCallable <BulkMutation , Void > externalBulkMutateRowsCallable ;
169172 private final UnaryCallable <ConditionalRowMutation , Boolean > checkAndMutateRowCallable ;
170173 private final UnaryCallable <ReadModifyWriteRow , Row > readModifyWriteRowCallable ;
171174 private final UnaryCallable <PingAndWarmRequest , PingAndWarmResponse > pingAndWarmCallable ;
@@ -368,7 +371,9 @@ public EnhancedBigtableStub(
368371 bulkReadRowsCallable = createBulkReadRowsCallable (new DefaultRowAdapter ());
369372 sampleRowKeysCallable = createSampleRowKeysCallable ();
370373 mutateRowCallable = createMutateRowCallable ();
371- bulkMutateRowsCallable = createBulkMutateRowsCallable ();
374+ bulkMutateRowsCallable = createMutateRowsBaseCallable ();
375+ externalBulkMutateRowsCallable =
376+ new MutateRowsErrorConverterUnaryCallable (bulkMutateRowsCallable );
372377 checkAndMutateRowCallable = createCheckAndMutateRowCallable ();
373378 readModifyWriteRowCallable = createReadModifyWriteRowCallable ();
374379 generateInitialChangeStreamPartitionsCallable =
@@ -665,14 +670,24 @@ public Map<String, String> extract(MutateRowRequest mutateRowRequest) {
665670 }
666671
667672 /**
668- * Internal helper to create the base MutateRows callable chain. The chain is responsible for
669- * retrying individual entry in case of error.
673+ * Creates a callable chain to handle MutatesRows RPCs. This is meant to be used for manual
674+ * batching. The chain will:
670675 *
671- * <p>NOTE: the caller is responsible for adding tracing & metrics.
676+ * <ul>
677+ * <li>Convert a {@link BulkMutation} into a {@link MutateRowsRequest}.
678+ * <li>Process the response and schedule retries. At the end of each attempt, entries that have
679+ * been applied, are filtered from the next attempt. Also, any entries that failed with a
680+ * nontransient error, are filtered from the next attempt. This will continue until there
681+ * are no more entries or there are no more retry attempts left.
682+ * <li>Wrap batch failures in a {@link MutateRowsAttemptResult}.
683+ * <li>Add tracing & metrics.
684+ * </ul>
685+ *
686+ * This callable returns an internal type {@link MutateRowsAttemptResult}.
672687 *
673- * @see MutateRowsRetryingCallable for more details
688+ * <p>This function should not be exposed to external users, as it could cause a data loss.
674689 */
675- private UnaryCallable <MutateRowsRequest , Void > createMutateRowsBaseCallable () {
690+ private UnaryCallable <BulkMutation , MutateRowsAttemptResult > createMutateRowsBaseCallable () {
676691 ServerStreamingCallable <MutateRowsRequest , MutateRowsResponse > base =
677692 GrpcRawCallableFactory .createServerStreamingCallable (
678693 GrpcCallSettings .<MutateRowsRequest , MutateRowsResponse >newBuilder ()
@@ -706,55 +721,38 @@ public Map<String, String> extract(MutateRowsRequest mutateRowsRequest) {
706721 ServerStreamingCallable <MutateRowsRequest , MutateRowsResponse > withBigtableTracer =
707722 new BigtableTracerStreamingCallable <>(convertException );
708723
709- BasicResultRetryAlgorithm <Void > resultRetryAlgorithm ;
724+ BasicResultRetryAlgorithm <MutateRowsAttemptResult > resultRetryAlgorithm ;
710725 if (settings .getEnableRetryInfo ()) {
711726 resultRetryAlgorithm = new RetryInfoRetryAlgorithm <>();
712727 } else {
713728 resultRetryAlgorithm = new ApiResultRetryAlgorithm <>();
714729 }
730+ MutateRowsPartialErrorRetryAlgorithm mutateRowsPartialErrorRetryAlgorithm =
731+ new MutateRowsPartialErrorRetryAlgorithm (resultRetryAlgorithm );
715732
716- RetryAlgorithm <Void > retryAlgorithm =
733+ RetryAlgorithm <MutateRowsAttemptResult > retryAlgorithm =
717734 new RetryAlgorithm <>(
718- resultRetryAlgorithm ,
735+ mutateRowsPartialErrorRetryAlgorithm ,
719736 new ExponentialRetryAlgorithm (
720737 settings .bulkMutateRowsSettings ().getRetrySettings (), clientContext .getClock ()));
721738
722- RetryingExecutorWithContext <Void > retryingExecutor =
739+ RetryingExecutorWithContext <MutateRowsAttemptResult > retryingExecutor =
723740 new ScheduledRetryingExecutor <>(retryAlgorithm , clientContext .getExecutor ());
741+ UnaryCallable <MutateRowsRequest , MutateRowsAttemptResult > baseCallable =
742+ new MutateRowsRetryingCallable (
743+ clientContext .getDefaultCallContext (),
744+ withBigtableTracer ,
745+ retryingExecutor ,
746+ settings .bulkMutateRowsSettings ().getRetryableCodes (),
747+ retryAlgorithm );
724748
725- return new MutateRowsRetryingCallable (
726- clientContext .getDefaultCallContext (),
727- withBigtableTracer ,
728- retryingExecutor ,
729- settings .bulkMutateRowsSettings ().getRetryableCodes (),
730- retryAlgorithm );
731- }
732-
733- /**
734- * Creates a callable chain to handle MutatesRows RPCs. This is meant to be used for manual
735- * batching. The chain will:
736- *
737- * <ul>
738- * <li>Convert a {@link BulkMutation} into a {@link MutateRowsRequest}.
739- * <li>Process the response and schedule retries. At the end of each attempt, entries that have
740- * been applied, are filtered from the next attempt. Also, any entries that failed with a
741- * nontransient error, are filtered from the next attempt. This will continue until there
742- * are no more entries or there are no more retry attempts left.
743- * <li>Wrap batch failures in a {@link
744- * com.google.cloud.bigtable.data.v2.models.MutateRowsException}.
745- * <li>Add tracing & metrics.
746- * </ul>
747- */
748- private UnaryCallable <BulkMutation , Void > createBulkMutateRowsCallable () {
749- UnaryCallable <MutateRowsRequest , Void > baseCallable = createMutateRowsBaseCallable ();
750-
751- UnaryCallable <MutateRowsRequest , Void > withCookie = baseCallable ;
749+ UnaryCallable <MutateRowsRequest , MutateRowsAttemptResult > withCookie = baseCallable ;
752750
753751 if (settings .getEnableRoutingCookie ()) {
754752 withCookie = new CookiesUnaryCallable <>(baseCallable );
755753 }
756754
757- UnaryCallable <MutateRowsRequest , Void > flowControlCallable = null ;
755+ UnaryCallable <MutateRowsRequest , MutateRowsAttemptResult > flowControlCallable = null ;
758756 if (settings .bulkMutateRowsSettings ().isLatencyBasedThrottlingEnabled ()) {
759757 flowControlCallable =
760758 new DynamicFlowControlCallable (
@@ -764,16 +762,16 @@ private UnaryCallable<BulkMutation, Void> createBulkMutateRowsCallable() {
764762 settings .bulkMutateRowsSettings ().getTargetRpcLatencyMs (),
765763 FLOW_CONTROL_ADJUSTING_INTERVAL_MS );
766764 }
767- UnaryCallable <BulkMutation , Void > userFacing =
765+ UnaryCallable <BulkMutation , MutateRowsAttemptResult > userFacing =
768766 new BulkMutateRowsUserFacingCallable (
769767 flowControlCallable != null ? flowControlCallable : withCookie , requestContext );
770768
771769 SpanName spanName = getSpanName ("MutateRows" );
772770
773- UnaryCallable <BulkMutation , Void > tracedBatcherUnaryCallable =
771+ UnaryCallable <BulkMutation , MutateRowsAttemptResult > tracedBatcherUnaryCallable =
774772 new TracedBatcherUnaryCallable <>(userFacing );
775773
776- UnaryCallable <BulkMutation , Void > traced =
774+ UnaryCallable <BulkMutation , MutateRowsAttemptResult > traced =
777775 new TracedUnaryCallable <>(
778776 tracedBatcherUnaryCallable , clientContext .getTracerFactory (), spanName );
779777
@@ -1171,10 +1169,15 @@ public UnaryCallable<RowMutation, Void> mutateRowCallable() {
11711169 }
11721170
11731171 /**
1174- * Returns the callable chain created in {@link #createBulkMutateRowsCallable()} ()} during stub
1172+ * Returns the callable chain created in {@link #createMutateRowsBaseCallable ()} during stub
11751173 * construction.
11761174 */
11771175 public UnaryCallable <BulkMutation , Void > bulkMutateRowsCallable () {
1176+ return externalBulkMutateRowsCallable ;
1177+ }
1178+
1179+ @ InternalApi
1180+ public UnaryCallable <BulkMutation , MutateRowsAttemptResult > internalBulkMutateRowsCallable () {
11781181 return bulkMutateRowsCallable ;
11791182 }
11801183
0 commit comments