mirror of https://github.com/grpc/grpc-java.git
Focus MultiChildLB updates around ResolvedAddresses of children
This makes ClusterManagerLB more straight-forward, focusing on just the things that are relevant to it, and it avoids specialized map key handling in updateChildrenWithResolvedAddresses().
This commit is contained in:
parent
4cb6465194
commit
cfecc4754b
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package io.grpc.util;
|
package io.grpc.util;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.grpc.ConnectivityState.CONNECTING;
|
import static io.grpc.ConnectivityState.CONNECTING;
|
||||||
import static io.grpc.ConnectivityState.IDLE;
|
import static io.grpc.ConnectivityState.IDLE;
|
||||||
|
|
@ -80,20 +79,20 @@ public abstract class MultiChildLoadBalancer extends LoadBalancer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override to utilize parsing of the policy configuration or alternative helper/lb generation.
|
* Override to utilize parsing of the policy configuration or alternative helper/lb generation.
|
||||||
|
* Override this if keys are not Endpoints or if child policies have configuration.
|
||||||
*/
|
*/
|
||||||
protected Map<Object, ChildLbState> createChildLbMap(ResolvedAddresses resolvedAddresses) {
|
protected Map<Object, ResolvedAddresses> createChildAddressesMap(
|
||||||
Map<Object, ChildLbState> childLbMap = new HashMap<>();
|
ResolvedAddresses resolvedAddresses) {
|
||||||
List<EquivalentAddressGroup> addresses = resolvedAddresses.getAddresses();
|
Map<Object, ResolvedAddresses> childAddresses = new HashMap<>();
|
||||||
for (EquivalentAddressGroup eag : addresses) {
|
for (EquivalentAddressGroup eag : resolvedAddresses.getAddresses()) {
|
||||||
Endpoint endpoint = new Endpoint(eag); // keys need to be just addresses
|
ResolvedAddresses addresses = resolvedAddresses.toBuilder()
|
||||||
ChildLbState existingChildLbState = childLbStates.get(endpoint);
|
.setAddresses(Collections.singletonList(eag))
|
||||||
if (existingChildLbState != null) {
|
.setAttributes(Attributes.newBuilder().set(IS_PETIOLE_POLICY, true).build())
|
||||||
childLbMap.put(endpoint, existingChildLbState);
|
.setLoadBalancingPolicyConfig(null)
|
||||||
} else {
|
.build();
|
||||||
childLbMap.put(endpoint, createChildLbState(endpoint));
|
childAddresses.put(new Endpoint(eag), addresses);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return childLbMap;
|
return childAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -128,39 +127,6 @@ public abstract class MultiChildLoadBalancer extends LoadBalancer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Override this if your keys are not of type Endpoint.
|
|
||||||
* @param key Key to identify the ChildLbState
|
|
||||||
* @param resolvedAddresses list of addresses which include attributes
|
|
||||||
* @return a fully loaded ResolvedAddresses object for the specified key
|
|
||||||
*/
|
|
||||||
protected ResolvedAddresses getChildAddresses(Object key, ResolvedAddresses resolvedAddresses) {
|
|
||||||
Endpoint endpointKey;
|
|
||||||
if (key instanceof EquivalentAddressGroup) {
|
|
||||||
endpointKey = new Endpoint((EquivalentAddressGroup) key);
|
|
||||||
} else {
|
|
||||||
checkArgument(key instanceof Endpoint, "key is wrong type");
|
|
||||||
endpointKey = (Endpoint) key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the non-stripped version
|
|
||||||
EquivalentAddressGroup eagToUse = null;
|
|
||||||
for (EquivalentAddressGroup currEag : resolvedAddresses.getAddresses()) {
|
|
||||||
if (endpointKey.equals(new Endpoint(currEag))) {
|
|
||||||
eagToUse = currEag;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNotNull(eagToUse, key + " no longer present in load balancer children");
|
|
||||||
|
|
||||||
return resolvedAddresses.toBuilder()
|
|
||||||
.setAddresses(Collections.singletonList(eagToUse))
|
|
||||||
.setAttributes(Attributes.newBuilder().set(IS_PETIOLE_POLICY, true).build())
|
|
||||||
.setLoadBalancingPolicyConfig(null)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the name resolution error.
|
* Handle the name resolution error.
|
||||||
*
|
*
|
||||||
|
|
@ -192,41 +158,31 @@ public abstract class MultiChildLoadBalancer extends LoadBalancer {
|
||||||
ResolvedAddresses resolvedAddresses) {
|
ResolvedAddresses resolvedAddresses) {
|
||||||
logger.log(Level.FINE, "Received resolution result: {0}", resolvedAddresses);
|
logger.log(Level.FINE, "Received resolution result: {0}", resolvedAddresses);
|
||||||
|
|
||||||
// Subclass handles any special manipulation to create appropriate types of keyed ChildLbStates
|
Map<Object, ResolvedAddresses> newChildAddresses = createChildAddressesMap(resolvedAddresses);
|
||||||
Map<Object, ChildLbState> newChildren = createChildLbMap(resolvedAddresses);
|
|
||||||
|
|
||||||
// Handle error case
|
// Handle error case
|
||||||
if (newChildren.isEmpty()) {
|
if (newChildAddresses.isEmpty()) {
|
||||||
Status unavailableStatus = Status.UNAVAILABLE.withDescription(
|
Status unavailableStatus = Status.UNAVAILABLE.withDescription(
|
||||||
"NameResolver returned no usable address. " + resolvedAddresses);
|
"NameResolver returned no usable address. " + resolvedAddresses);
|
||||||
handleNameResolutionError(unavailableStatus);
|
handleNameResolutionError(unavailableStatus);
|
||||||
return new AcceptResolvedAddrRetVal(unavailableStatus, null);
|
return new AcceptResolvedAddrRetVal(unavailableStatus, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
addMissingChildren(newChildren);
|
updateChildrenWithResolvedAddresses(newChildAddresses);
|
||||||
|
|
||||||
updateChildrenWithResolvedAddresses(resolvedAddresses, newChildren);
|
return new AcceptResolvedAddrRetVal(Status.OK, getRemovedChildren(newChildAddresses.keySet()));
|
||||||
|
|
||||||
return new AcceptResolvedAddrRetVal(Status.OK, getRemovedChildren(newChildren.keySet()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMissingChildren(Map<Object, ChildLbState> newChildren) {
|
private void updateChildrenWithResolvedAddresses(
|
||||||
// Do adds and identify reused children
|
Map<Object, ResolvedAddresses> newChildAddresses) {
|
||||||
for (Map.Entry<Object, ChildLbState> entry : newChildren.entrySet()) {
|
for (Map.Entry<Object, ResolvedAddresses> entry : newChildAddresses.entrySet()) {
|
||||||
final Object key = entry.getKey();
|
|
||||||
if (!childLbStates.containsKey(key)) {
|
|
||||||
childLbStates.put(key, entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateChildrenWithResolvedAddresses(ResolvedAddresses resolvedAddresses,
|
|
||||||
Map<Object, ChildLbState> newChildren) {
|
|
||||||
for (Map.Entry<Object, ChildLbState> entry : newChildren.entrySet()) {
|
|
||||||
ChildLbState childLbState = childLbStates.get(entry.getKey());
|
ChildLbState childLbState = childLbStates.get(entry.getKey());
|
||||||
ResolvedAddresses childAddresses = getChildAddresses(entry.getKey(), resolvedAddresses);
|
if (childLbState == null) {
|
||||||
childLbState.setResolvedAddresses(childAddresses); // update child
|
childLbState = createChildLbState(entry.getKey());
|
||||||
childLbState.lb.handleResolvedAddresses(childAddresses); // update child LB
|
childLbStates.put(entry.getKey(), childLbState);
|
||||||
|
}
|
||||||
|
childLbState.setResolvedAddresses(entry.getValue()); // update child
|
||||||
|
childLbState.lb.handleResolvedAddresses(entry.getValue()); // update child LB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,31 +70,28 @@ class ClusterManagerLoadBalancer extends MultiChildLoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ResolvedAddresses getChildAddresses(Object key, ResolvedAddresses resolvedAddresses) {
|
protected ChildLbState createChildLbState(Object key) {
|
||||||
ClusterManagerConfig config = (ClusterManagerConfig)
|
return new ClusterManagerLbState(key, GracefulSwitchLoadBalancerFactory.INSTANCE);
|
||||||
resolvedAddresses.getLoadBalancingPolicyConfig();
|
|
||||||
Object childConfig = config.childPolicies.get(key);
|
|
||||||
return resolvedAddresses.toBuilder().setLoadBalancingPolicyConfig(childConfig).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<Object, ChildLbState> createChildLbMap(ResolvedAddresses resolvedAddresses) {
|
protected Map<Object, ResolvedAddresses> createChildAddressesMap(
|
||||||
|
ResolvedAddresses resolvedAddresses) {
|
||||||
ClusterManagerConfig config = (ClusterManagerConfig)
|
ClusterManagerConfig config = (ClusterManagerConfig)
|
||||||
resolvedAddresses.getLoadBalancingPolicyConfig();
|
resolvedAddresses.getLoadBalancingPolicyConfig();
|
||||||
Map<Object, ChildLbState> newChildPolicies = new HashMap<>();
|
Map<Object, ResolvedAddresses> childAddresses = new HashMap<>();
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
for (String key : config.childPolicies.keySet()) {
|
for (Map.Entry<String, Object> childPolicy : config.childPolicies.entrySet()) {
|
||||||
ChildLbState child = getChildLbState(key);
|
ResolvedAddresses addresses = resolvedAddresses.toBuilder()
|
||||||
if (child == null) {
|
.setLoadBalancingPolicyConfig(childPolicy.getValue())
|
||||||
child = new ClusterManagerLbState(key, GracefulSwitchLoadBalancerFactory.INSTANCE);
|
.build();
|
||||||
}
|
childAddresses.put(childPolicy.getKey(), addresses);
|
||||||
newChildPolicies.put(key, child);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.log(
|
||||||
XdsLogLevel.INFO,
|
XdsLogLevel.INFO,
|
||||||
"Received cluster_manager lb config: child names={0}", newChildPolicies.keySet());
|
"Received cluster_manager lb config: child names={0}", childAddresses.keySet());
|
||||||
return newChildPolicies;
|
return childAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue