Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
import io.grpc.Attributes;
import io.grpc.ChannelLogger.ChannelLogLevel;
import io.grpc.ConnectivityState;
import io.grpc.ConnectivityStateInfo;
import io.grpc.EquivalentAddressGroup;
import io.grpc.LoadBalancer;
import io.grpc.LoadBalancer.Helper;
import io.grpc.LoadBalancer.PickResult;
import io.grpc.LoadBalancer.PickSubchannelArgs;
import io.grpc.LoadBalancer.SubchannelPicker;
import io.grpc.LoadBalancerProvider;
import io.grpc.LoadBalancerRegistry;
import io.grpc.Status;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import javax.annotation.Nullable;
public final class AutoConfiguredLoadBalancerFactory extends LoadBalancer.Factory {
private static final Logger logger =
Logger.getLogger(AutoConfiguredLoadBalancerFactory.class.getName());
private final LoadBalancerRegistry registry;
private final String defaultPolicy;
public AutoConfiguredLoadBalancerFactory(String defaultPolicy) {
this(LoadBalancerRegistry.getDefaultRegistry(), defaultPolicy);
}
@VisibleForTesting
AutoConfiguredLoadBalancerFactory(LoadBalancerRegistry registry, String defaultPolicy) {
this.registry = checkNotNull(registry, "registry");
this.defaultPolicy = checkNotNull(defaultPolicy, "defaultPolicy");
}
@Override
public LoadBalancer newLoadBalancer(Helper helper) {
return new AutoConfiguredLoadBalancer(helper);
}
private static final class NoopLoadBalancer extends LoadBalancer {
@Override
public void handleResolvedAddressGroups(List s, Attributes a) {}
@Override
public void handleNameResolutionError(Status error) {}
@Override
public void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {}
@Override
public void shutdown() {}
}
@VisibleForTesting
public final class AutoConfiguredLoadBalancer extends LoadBalancer {
private final Helper helper;
private LoadBalancer delegate;
private LoadBalancerProvider delegateProvider;
private boolean roundRobinDueToGrpclbDepMissing;
AutoConfiguredLoadBalancer(Helper helper) {
this.helper = helper;
delegateProvider = registry.getProvider(defaultPolicy);
if (delegateProvider == null) {
throw new IllegalStateException("Could not find policy '" + defaultPolicy
+ "'. Make sure its implementation is either registered to LoadBalancerRegistry or"
+ " included in META-INF/services/io.grpc.LoadBalancerProvider from your jar files.");
}
delegate = delegateProvider.newLoadBalancer(helper);
}
// Must be run inside ChannelExecutor.
@Override
public void handleResolvedAddressGroups(
List servers, Attributes attributes) {
if (attributes.get(ATTR_LOAD_BALANCING_CONFIG) != null) {
throw new IllegalArgumentException(
"Unexpected ATTR_LOAD_BALANCING_CONFIG from upstream: "
+ attributes.get(ATTR_LOAD_BALANCING_CONFIG));
}
Map configMap = attributes.get(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG);
PolicySelection selection;
try {
selection = decideLoadBalancerProvider(servers, configMap);
} catch (PolicyException e) {
Status s = Status.INTERNAL.withDescription(e.getMessage());
helper.updateBalancingState(ConnectivityState.TRANSIENT_FAILURE, new FailingPicker(s));
delegate.shutdown();
delegateProvider = null;
delegate = new NoopLoadBalancer();
return;
}
if (delegateProvider == null
|| !selection.provider.getPolicyName().equals(delegateProvider.getPolicyName())) {
helper.updateBalancingState(ConnectivityState.CONNECTING, new EmptyPicker());
delegate.shutdown();
delegateProvider = selection.provider;
LoadBalancer old = delegate;
delegate = delegateProvider.newLoadBalancer(helper);
helper.getChannelLogger().log(
ChannelLogLevel.INFO, "Load balancer changed from {0} to {1}",
old.getClass().getSimpleName(), delegate.getClass().getSimpleName());
}
if (selection.config != null) {
helper.getChannelLogger().log(
ChannelLogLevel.DEBUG, "Load-balancing config: {0}", selection.config);
attributes =
attributes.toBuilder().set(ATTR_LOAD_BALANCING_CONFIG, selection.config).build();
}
LoadBalancer delegate = getDelegate();
if (selection.serverList.isEmpty()
&& !delegate.canHandleEmptyAddressListFromNameResolution()) {
delegate.handleNameResolutionError(
Status.UNAVAILABLE.withDescription(
"Name resolver returned no usable address. addrs="
+ servers + ", attrs=" + attributes));
} else {
delegate.handleResolvedAddressGroups(selection.serverList, attributes);
}
}
@Override
public void handleNameResolutionError(Status error) {
getDelegate().handleNameResolutionError(error);
}
@Override
public void handleSubchannelState(Subchannel subchannel, ConnectivityStateInfo stateInfo) {
getDelegate().handleSubchannelState(subchannel, stateInfo);
}
@Override
public boolean canHandleEmptyAddressListFromNameResolution() {
return true;
}
@Override
public void shutdown() {
delegate.shutdown();
delegate = null;
}
@VisibleForTesting
public LoadBalancer getDelegate() {
return delegate;
}
@VisibleForTesting
void setDelegate(LoadBalancer lb) {
delegate = lb;
}
@VisibleForTesting
LoadBalancerProvider getDelegateProvider() {
return delegateProvider;
}
/**
* Picks a load balancer based on given criteria. In order of preference:
*
*
*
User provided lb on the channel. This is a degenerate case and not handled here.
*
"grpclb" if any gRPC LB balancer addresses are present
*
The policy picked by the service config
*
"pick_first" if the service config choice does not specify
*
*
* @param servers The list of servers reported
* @param config the service config object
* @return the new load balancer factory, never null
*/
@VisibleForTesting
PolicySelection decideLoadBalancerProvider(
List servers, @Nullable Map config)
throws PolicyException {
// Check for balancer addresses
boolean haveBalancerAddress = false;
List backendAddrs = new ArrayList<>();
for (EquivalentAddressGroup s : servers) {
if (s.getAttributes().get(GrpcAttributes.ATTR_LB_ADDR_AUTHORITY) != null) {
haveBalancerAddress = true;
} else {
backendAddrs.add(s);
}
}
if (haveBalancerAddress) {
LoadBalancerProvider grpclbProvider = registry.getProvider("grpclb");
if (grpclbProvider == null) {
if (backendAddrs.isEmpty()) {
throw new PolicyException(
"Received ONLY balancer addresses but grpclb runtime is missing");
}
if (!roundRobinDueToGrpclbDepMissing) {
roundRobinDueToGrpclbDepMissing = true;
String errorMsg = "Found balancer addresses but grpclb runtime is missing."
+ " Will use round_robin. Please include grpc-grpclb in your runtime depedencies.";
helper.getChannelLogger().log(ChannelLogLevel.ERROR, errorMsg);
logger.warning(errorMsg);
}
return new PolicySelection(
getProviderOrThrow(
"round_robin", "received balancer addresses but grpclb runtime is missing"),
backendAddrs, null);
} else {
return new PolicySelection(grpclbProvider, servers, null);
}
}
roundRobinDueToGrpclbDepMissing = false;
List