mirror of https://github.com/grpc/grpc-java.git
xds: use order-deterministic locality map for preserving most recent locality update to eliminate test flakiness (#5921)
* xds: use order-deterministic locality map for preserving most recent locality update to eliminate test flakiness * make localityMap immutable
This commit is contained in:
parent
5edd726551
commit
44bbccff79
|
|
@ -26,6 +26,7 @@ import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import io.grpc.ConnectivityState;
|
import io.grpc.ConnectivityState;
|
||||||
import io.grpc.ConnectivityStateInfo;
|
import io.grpc.ConnectivityStateInfo;
|
||||||
import io.grpc.EquivalentAddressGroup;
|
import io.grpc.EquivalentAddressGroup;
|
||||||
|
|
@ -49,9 +50,8 @@ import io.grpc.xds.XdsComms.LocalityInfo;
|
||||||
import io.grpc.xds.XdsSubchannelPickers.ErrorPicker;
|
import io.grpc.xds.XdsSubchannelPickers.ErrorPicker;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -84,7 +84,7 @@ interface LocalityStore {
|
||||||
private final StatsStore statsStore;
|
private final StatsStore statsStore;
|
||||||
private final OrcaPerRequestUtil orcaPerRequestUtil;
|
private final OrcaPerRequestUtil orcaPerRequestUtil;
|
||||||
|
|
||||||
private Map<XdsLocality, LocalityLbInfo> localityMap = new HashMap<>();
|
private Map<XdsLocality, LocalityLbInfo> localityMap = ImmutableMap.of();
|
||||||
private ImmutableList<DropOverload> dropOverloads = ImmutableList.of();
|
private ImmutableList<DropOverload> dropOverloads = ImmutableList.of();
|
||||||
|
|
||||||
LocalityStoreImpl(Helper helper, LoadBalancerRegistry lbRegistry) {
|
LocalityStoreImpl(Helper helper, LoadBalancerRegistry lbRegistry) {
|
||||||
|
|
@ -177,7 +177,7 @@ interface LocalityStore {
|
||||||
localityMap.get(locality).shutdown();
|
localityMap.get(locality).shutdown();
|
||||||
statsStore.removeLocality(locality);
|
statsStore.removeLocality(locality);
|
||||||
}
|
}
|
||||||
localityMap = new HashMap<>();
|
localityMap = ImmutableMap.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is triggered by EDS response.
|
// This is triggered by EDS response.
|
||||||
|
|
@ -185,20 +185,14 @@ interface LocalityStore {
|
||||||
public void updateLocalityStore(Map<XdsLocality, LocalityInfo> localityInfoMap) {
|
public void updateLocalityStore(Map<XdsLocality, LocalityInfo> localityInfoMap) {
|
||||||
Set<XdsLocality> oldLocalities = localityMap.keySet();
|
Set<XdsLocality> oldLocalities = localityMap.keySet();
|
||||||
Set<XdsLocality> newLocalities = localityInfoMap.keySet();
|
Set<XdsLocality> newLocalities = localityInfoMap.keySet();
|
||||||
|
Map<XdsLocality, LocalityLbInfo> updatedLocalityMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
final Set<XdsLocality> toRemove = new HashSet<>();
|
final Set<XdsLocality> toRemove = new HashSet<>();
|
||||||
Iterator<XdsLocality> iterator = oldLocalities.iterator();
|
for (XdsLocality oldLocality : oldLocalities) {
|
||||||
while (iterator.hasNext()) {
|
|
||||||
XdsLocality oldLocality = iterator.next();
|
|
||||||
if (!newLocalities.contains(oldLocality)) {
|
if (!newLocalities.contains(oldLocality)) {
|
||||||
toRemove.add(oldLocality);
|
toRemove.add(oldLocality);
|
||||||
// No graceful transition until a high-level lb graceful transition design is available.
|
// No graceful transition until a high-level lb graceful transition design is available.
|
||||||
localityMap.get(oldLocality).shutdown();
|
localityMap.get(oldLocality).shutdown();
|
||||||
iterator.remove();
|
|
||||||
if (localityMap.isEmpty()) {
|
|
||||||
// down-size the map
|
|
||||||
localityMap = new HashMap<>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,11 +205,10 @@ interface LocalityStore {
|
||||||
LocalityLbInfo localityLbInfo;
|
LocalityLbInfo localityLbInfo;
|
||||||
ChildHelper childHelper;
|
ChildHelper childHelper;
|
||||||
if (oldLocalities.contains(newLocality)) {
|
if (oldLocalities.contains(newLocality)) {
|
||||||
LocalityLbInfo oldLocalityLbInfo
|
LocalityLbInfo oldLocalityLbInfo = localityMap.get(newLocality);
|
||||||
= localityMap.get(newLocality);
|
|
||||||
childHelper = oldLocalityLbInfo.childHelper;
|
childHelper = oldLocalityLbInfo.childHelper;
|
||||||
localityLbInfo = new LocalityLbInfo(
|
localityLbInfo =
|
||||||
localityInfoMap.get(newLocality).localityWeight,
|
new LocalityLbInfo(oldLocalityLbInfo.localityWeight,
|
||||||
oldLocalityLbInfo.childBalancer,
|
oldLocalityLbInfo.childBalancer,
|
||||||
childHelper);
|
childHelper);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -226,8 +219,8 @@ interface LocalityStore {
|
||||||
localityInfoMap.get(newLocality).localityWeight,
|
localityInfoMap.get(newLocality).localityWeight,
|
||||||
loadBalancerProvider.newLoadBalancer(childHelper),
|
loadBalancerProvider.newLoadBalancer(childHelper),
|
||||||
childHelper);
|
childHelper);
|
||||||
localityMap.put(newLocality, localityLbInfo);
|
|
||||||
}
|
}
|
||||||
|
updatedLocalityMap.put(newLocality, localityLbInfo);
|
||||||
// TODO: put endPointWeights into attributes for WRR.
|
// TODO: put endPointWeights into attributes for WRR.
|
||||||
localityLbInfo.childBalancer
|
localityLbInfo.childBalancer
|
||||||
.handleResolvedAddresses(
|
.handleResolvedAddresses(
|
||||||
|
|
@ -241,6 +234,7 @@ interface LocalityStore {
|
||||||
}
|
}
|
||||||
newState = aggregateState(newState, childHelper.currentChildState);
|
newState = aggregateState(newState, childHelper.currentChildState);
|
||||||
}
|
}
|
||||||
|
localityMap = Collections.unmodifiableMap(updatedLocalityMap);
|
||||||
|
|
||||||
updatePicker(newState, childPickers);
|
updatePicker(newState, childPickers);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue