public void execute() throws Exception {
    final String activeShardCountFailure = checkActiveShardCount();
    final ShardRouting primaryRouting = primary.routingEntry();
    final ShardId primaryId = primaryRouting.shardId();
    if (activeShardCountFailure != null) {
      finishAsFailed(
          new UnavailableShardsException(
              primaryId,
              "{} Timeout: [{}], request: [{}]",
              activeShardCountFailure,
              request.timeout(),
              request));
      return;
    }

    totalShards.incrementAndGet();
    pendingShards.incrementAndGet();
    primaryResult = primary.perform(request);
    final ReplicaRequest replicaRequest = primaryResult.replicaRequest();
    assert replicaRequest.primaryTerm() > 0 : "replicaRequest doesn't have a primary term";
    if (logger.isTraceEnabled()) {
      logger.trace(
          "[{}] op [{}] completed on primary for request [{}]", primaryId, opType, request);
    }

    performOnReplicas(primaryId, replicaRequest);

    successfulShards.incrementAndGet();
    decPendingAndFinishIfNeeded();
  }
 private void finish() {
   if (finished.compareAndSet(false, true)) {
     final ReplicationResponse.ShardInfo.Failure[] failuresArray;
     if (shardReplicaFailures.isEmpty()) {
       failuresArray = ReplicationResponse.EMPTY;
     } else {
       failuresArray = new ReplicationResponse.ShardInfo.Failure[shardReplicaFailures.size()];
       shardReplicaFailures.toArray(failuresArray);
     }
     primaryResult.setShardInfo(
         new ReplicationResponse.ShardInfo(
             totalShards.get(), successfulShards.get(), failuresArray));
     resultListener.onResponse(primaryResult);
   }
 }