in wrapper/src/main/java/software/amazon/jdbc/RoundRobinHostSelector.java [74:131]
public HostSpec getHost(
final @NonNull List<HostSpec> hosts,
final @NonNull HostRole role,
final @Nullable Properties props) throws SQLException {
lock.lock();
try {
final List<HostSpec> eligibleHosts = hosts.stream()
.filter(hostSpec ->
role.equals(hostSpec.getRole()) && hostSpec.getAvailability().equals(HostAvailability.AVAILABLE))
.sorted(Comparator.comparing(HostSpec::getHost))
.collect(Collectors.toList());
if (eligibleHosts.isEmpty()) {
throw new SQLException(Messages.get("HostSelector.noHostsMatchingRole", new Object[]{role}));
}
// Create new cache entries for provided hosts if necessary. All hosts point to the same cluster info.
createCacheEntryForHosts(eligibleHosts, props);
final String currentClusterInfoKey = eligibleHosts.get(0).getHost();
final RoundRobinClusterInfo clusterInfo = roundRobinCache.get(currentClusterInfoKey);
final HostSpec lastHost = clusterInfo.lastHost;
int lastHostIndex = -1;
// Check if lastHost is in list of eligible hosts. Update lastHostIndex.
if (lastHost != null) {
for (int i = 0; i < eligibleHosts.size(); i++) {
if (eligibleHosts.get(i).getHost().equals(lastHost.getHost())) {
lastHostIndex = i;
}
}
}
final int targetHostIndex;
// If the host is weighted and the lastHost is in the eligibleHosts list.
if (clusterInfo.weightCounter > 0 && lastHostIndex != -1) {
targetHostIndex = lastHostIndex;
} else {
if (lastHostIndex != -1 && lastHostIndex != eligibleHosts.size() - 1) {
targetHostIndex = lastHostIndex + 1;
} else {
targetHostIndex = 0;
}
final Integer weight = clusterInfo.clusterWeightsMap.get(eligibleHosts.get(targetHostIndex).getHostId());
clusterInfo.weightCounter = weight == null ? clusterInfo.defaultWeight : weight;
}
clusterInfo.weightCounter--;
clusterInfo.lastHost = eligibleHosts.get(targetHostIndex);
return eligibleHosts.get(targetHostIndex);
} finally {
lock.unlock();
}
}