java-driver
java-driver copied to clipboard
[3.x] `RackAwareRoundRobinPolicy` seems incompatible with `ReplicaOrdering.RANDOM` in `TokenAwarePolicy`
See the following snippet from TokenAwarePolicy.java
@Override
protected Host computeNext() {
while (replicasIterator.hasNext()) {
Host host = replicasIterator.next();
if (host.isUp() && childPolicy.distance(host) == HostDistance.LOCAL) return host;
}
...
This is how we calculate the first hosts in query plan in case of ReplicaOrdering.RANDOM. We prioritise replicas (which have been random shuffled beforehand) and select first those that according to child policy are local replicas. The problem is with distance implementation of RackAwareRoundRobinPolicy
@Override
public HostDistance distance(Host host) {
String dc = dc(host);
if (dc == UNSET || dc.equals(localDc)) return HostDistance.LOCAL;
CopyOnWriteArrayList<Host> dcHosts = perDcLiveHosts.get(dc);
if (dcHosts == null || usedHostsPerRemoteDc == 0) return HostDistance.IGNORED;
// We need to clone, otherwise our subList call is not thread safe
dcHosts = cloneList(dcHosts);
return dcHosts.subList(0, Math.min(dcHosts.size(), usedHostsPerRemoteDc)).contains(host)
? HostDistance.REMOTE
: HostDistance.IGNORED;
}
On its own this policy prioritizes first local rack, then remote racks but in local DC then remote DCs. However, HostDistance right now only differentiates between LOCAL, REMOTE and IGNORED. If this policy is used with random ordering token aware policy then if remote rack but local dc replica comes first in the list of replicas, then it will be considered LOCAL according to this code snippet, invalidating the property of local rack going first. It's effectively DCAware and not RackAware in that configuration.