private void complete(TableName tableName, LocateRequest req, RegionLocations locs,
    Throwable error) {
    if (error != null) {
      LOG.warn("Failed to locate region in '" + tableName + "', row='"
        + Bytes.toStringBinary(req.row) + "', locateType=" + req.locateType, error);
    }
    Optional<LocateRequest> toSend = Optional.empty();
    TableCache tableCache = getTableCache(tableName);
    if (locs != null) {
      RegionLocations addedLocs = tableCache.regionLocationCache.add(locs);
      List<RegionLocationsFutureResult> futureResultList = new ArrayList<>();
      synchronized (tableCache) {
        tableCache.pendingRequests.remove(req);
        futureResultList.addAll(tableCache.clearCompletedRequests(addedLocs));
        // Remove a complete locate request in a synchronized block, so the table cache must have
        // quota to send a candidate request.
        toSend = tableCache.getCandidate();
        toSend.ifPresent(r -> tableCache.send(r));
      }
      futureResultList.forEach(RegionLocationsFutureResult::complete);
      toSend.ifPresent(r -> locateInMeta(tableName, r));
    } else {
      // we meet an error
      assert error != null;
      List<RegionLocationsFutureResult> futureResultList = new ArrayList<>();
      synchronized (tableCache) {
        tableCache.pendingRequests.remove(req);
        // fail the request itself, no matter whether it is a DoNotRetryIOException, as we have
        // already retried several times
        CompletableFuture<RegionLocations> future = tableCache.allRequests.remove(req);
        if (future != null) {
          futureResultList.add(new RegionLocationsFutureResult(future, null, error));
        }
        futureResultList.addAll(tableCache.clearCompletedRequests(null));
        // Remove a complete locate request in a synchronized block, so the table cache must have
        // quota to send a candidate request.
        toSend = tableCache.getCandidate();
        toSend.ifPresent(r -> tableCache.send(r));
      }
      futureResultList.forEach(RegionLocationsFutureResult::complete);
      toSend.ifPresent(r -> locateInMeta(tableName, r));
    }
  }
The asynchronous locator for regions other than meta.
hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java