docs: @Override
    public Void call() {
      try {
        Preconditions.checkNotNull(
            externalFuture, "External future must be set before starting an attempt");
  
        Preconditions.checkState(
            currentRequest.getEntriesCount() > 0, "Request doesn't have any mutations to send");
  
        // Configure the deadline
        ApiCallContext currentCallContext = callContext;
        if (!externalFuture.getAttemptSettings().getRpcTimeout().isZero()) {
          currentCallContext =
              currentCallContext.withTimeout(externalFuture.getAttemptSettings().getRpcTimeout());
        }
  
        // Handle concurrent cancellation
        externalFuture.setAttemptFuture(new NonCancellableFuture<Void>());
        if (externalFuture.isDone()) {
          return null;
        }
  
        callContext
            .getTracer()
            .attemptStarted(externalFuture.getAttemptSettings().getOverallAttemptCount());
  
        // Make the actual call
        ApiFuture<List<MutateRowsResponse>> innerFuture =
            innerCallable.futureCall(currentRequest, currentCallContext);
  
        // Handle RPC level errors by wrapping them in a MutateRowsException
        ApiFuture<List<MutateRowsResponse>> catching =
            ApiFutures.catching(
                innerFuture, Throwable.class, attemptFailedCallback, MoreExecutors.directExecutor());
  
        // Inspect the results and either propagate the success, or prepare to retry the failed
        // mutations
        ApiFuture<Void> transformed =
            ApiFutures.transform(catching, attemptSuccessfulCallback, MoreExecutors.directExecutor());
  
        // Notify the parent of the attempt
        externalFuture.setAttemptFuture(transformed);
      } catch (Throwable e) {
        externalFuture.setAttemptFuture(ApiFutures.<Void>immediateFailedFuture(e));
      }
  
      return null;
    }