private String selectRandomHostNameWithPreferenceOnAvailability(List<String> candidateHostNames) throws AmbariException {
    if (null == candidateHostNames || candidateHostNames.isEmpty()) {
      return null;
    }
    if (candidateHostNames.size() == 1) {
      return candidateHostNames.get(0);
    }

    List<String> hostsWithZeroCommands = new ArrayList<>();
    List<String> hostsWithInProgressCommands = new ArrayList<>();

    Map<Long, Integer> hostIdToCount = hostRoleCommandDAO.getHostIdToCountOfCommandsWithStatus(HostRoleStatus.IN_PROGRESS_STATUSES);
    for (String hostName : candidateHostNames) {
      Host host = clusters.getHost(hostName);

      if (hostIdToCount.containsKey(host.getHostId()) && hostIdToCount.get(host.getHostId()) > 0) {
        hostsWithInProgressCommands.add(hostName);
      } else {
        hostsWithZeroCommands.add(hostName);
      }
    }

    List<String> preferredList = !hostsWithZeroCommands.isEmpty() ? hostsWithZeroCommands : hostsWithInProgressCommands;
    if (!preferredList.isEmpty()) {
      int randomIndex = new Random().nextInt(preferredList.size());
      return preferredList.get(randomIndex);
    }

    return null;
  }
Assuming all hosts are healthy and not in maintenance mode. Rank the hosts based on availability.
Let S = all hosts with 0 PENDING/RUNNING/QUEUED/IN-PROGRESS tasks
Let S' be all such other hosts.

If S is non-empty, pick a random host from it. If S is empty and S' is non-empty, pick a random host from S'.
@param candidateHostNames All possible host names
@return Random host with a preference for those that are available to process commands immediately.
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java