private ReplicateWALEntryResponse replayToServer(List<Entry> entries, int timeout)
        throws IOException {
      // check whether we should still replay this entry. If the regions are changed, or the
      // entry is not coming form the primary region, filter it out because we do not need it.
      // Regions can change because of (1) region split (2) region merge (3) table recreated
      boolean skip = false;

      if (!Bytes.equals(
          location.getRegionInfo().getEncodedNameAsBytes(), initialEncodedRegionName)) {
        skip = true;
      }
      if (!entries.isEmpty() && !skip) {
        Entry[] entriesArray = new Entry[entries.size()];
        entriesArray = entries.toArray(entriesArray);

        // set the region name for the target region replica
        Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner> p =
            ReplicationProtbufUtil.buildReplicateWALEntryRequest(
                entriesArray, location.getRegionInfo().getEncodedNameAsBytes(), null, null, null);
        try {
          PayloadCarryingRpcController controller =
              rpcControllerFactory.newController(p.getSecond());
          controller.setCallTimeout(timeout);
          controller.setPriority(tableName);
          return stub.replay(controller, p.getFirst());
        } catch (ServiceException se) {
          throw ProtobufUtil.getRemoteException(se);
        }
      }

      if (skip) {
        if (LOG.isTraceEnabled()) {
          LOG.trace(
              "Skipping "
                  + entries.size()
                  + " entries in table "
                  + tableName
                  + " because located region "
                  + location.getRegionInfo().getEncodedName()
                  + " is different than the original region "
                  + Bytes.toStringBinary(initialEncodedRegionName)
                  + " from WALEdit");
          for (Entry entry : entries) {
            LOG.trace("Skipping : " + entry);
          }
        }
        skippedEntries.addAndGet(entries.size());
      }
      return ReplicateWALEntryResponse.newBuilder().build();
    }
 public ReplicaRegionServerCallable(int id, HRegionLocation location) {
   super(
       RpcRetryingCallerWithReadReplicas.this.cConnection,
       RpcRetryingCallerWithReadReplicas.this.tableName,
       get.getRow());
   this.id = id;
   this.location = location;
   this.controller = rpcControllerFactory.newController();
   controller.setPriority(tableName);
 }
    @Override
    public Result call(int callTimeout) throws Exception {
      if (controller.isCanceled()) return null;

      if (Thread.interrupted()) {
        throw new InterruptedIOException();
      }

      byte[] reg = location.getRegionInfo().getRegionName();

      ClientProtos.GetRequest request = RequestConverter.buildGetRequest(reg, get);
      controller.setCallTimeout(callTimeout);

      try {
        ClientProtos.GetResponse response = getStub().get(controller, request);
        if (response == null) {
          return null;
        }
        return ProtobufUtil.toResult(response.getResult());
      } catch (ServiceException se) {
        throw ProtobufUtil.getRemoteException(se);
      }
    }
    /**
     * Two responsibilities - if the call is already completed (by another replica) stops the
     * retries. - set the location to the right region, depending on the replica.
     */
    @Override
    public void prepare(final boolean reload) throws IOException {
      if (controller.isCanceled()) return;

      if (Thread.interrupted()) {
        throw new InterruptedIOException();
      }

      if (reload || location == null) {
        RegionLocations rl = getRegionLocations(false, id, cConnection, tableName, get.getRow());
        location = id < rl.size() ? rl.getRegionLocation(id) : null;
      }

      if (location == null || location.getServerName() == null) {
        // With this exception, there will be a retry. The location can be null for a replica
        //  when the table is created or after a split.
        throw new HBaseIOException("There is no location for replica id #" + id);
      }

      ServerName dest = location.getServerName();

      setStub(cConnection.getClient(dest));
    }
 @Override
 public boolean isCancelled() {
   return controller.isCanceled();
 }
 @Override
 public void cancel() {
   controller.startCancel();
 }