public void scheduleGetPRMetaData(final InternalRegion region, final boolean isRecursive,
      byte nwHopType) {
    if (nonPRs.contains(region.getFullPath())) {
      return;
    }
    ClientPartitionAdvisor advisor = getClientPartitionAdvisor(region.getFullPath());
    if (advisor != null && advisor.getServerGroup().length() != 0
        && HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP) {
      if (logger.isDebugEnabled()) {
        logger.debug("Scheduling metadata refresh: {} region: {}", nwHopType, region.getName());
      }
      if (nwHopType == PartitionedRegion.NETWORK_HOP_TO_DIFFERENT_GROUP) {
        return;
      }
    }
    synchronized (fetchTaskCountLock) {
      if (regionsBeingRefreshed.contains(region.getFullPath())) {
        return;
      }
    }
    if (isRecursive) {
      try {
        getClientPRMetadata(region);
      } catch (VirtualMachineError e) {
        SystemFailure.initiateFailure(e);
        throw e;
      } catch (Throwable e) {
        SystemFailure.checkFailure();
        if (logger.isDebugEnabled()) {
          logger.debug("An exception occurred while fetching metadata", e);
        }
      }
    } else {
      synchronized (fetchTaskCountLock) {
        if (regionsBeingRefreshed.contains(region.getFullPath())) {
          return;
        }
        regionsBeingRefreshed.add(region.getFullPath());
        refreshTaskCount++;
        totalRefreshTaskCount++;
      }
      Runnable fetchTask = () -> {
        try {
          getClientPRMetadata(region);
        } catch (VirtualMachineError e) {
          SystemFailure.initiateFailure(e);
          throw e;
        } catch (Throwable e) {
          SystemFailure.checkFailure();
          if (logger.isDebugEnabled()) {
            logger.debug("An exception occurred while fetching metadata", e);
          }
        } finally {
          synchronized (fetchTaskCountLock) {
            regionsBeingRefreshed.remove(region.getFullPath());
            refreshTaskCount--;
          }
        }
      };
      SingleHopClientExecutor.submitTask(fetchTask);
    }
  }
This function should make a map of server to buckets it is hosting. If for some bucket servers
are not available due to mismatch in metadata it should fill up a random server for it.
geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientMetadataService.java