Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ed5072e
Add Docker fiels for xds example server and client.
kannanjgithub May 20, 2025
c8be933
Merge branch 'grpc:master' into master
kannanjgithub Jun 3, 2025
63997fd
Merge branch 'grpc:master' into master
kannanjgithub Jun 6, 2025
5140beb
Merge branch 'grpc:master' into master
kannanjgithub Jun 11, 2025
029db63
Merge branch 'grpc:master' into master
kannanjgithub Jun 13, 2025
f472436
Merge branch 'grpc:master' into master
kannanjgithub Jun 23, 2025
459208c
in-progress changes.
kannanjgithub Jun 23, 2025
6cddc61
in-progress changes.
kannanjgithub Jun 24, 2025
f038f4c
in-progress changes.
kannanjgithub Jun 25, 2025
ad9b1b3
in-progress changes.
kannanjgithub Jun 25, 2025
d92902d
in-progress changes.
kannanjgithub Jun 26, 2025
60fae37
in-progress changes.
kannanjgithub Jun 26, 2025
6f0a920
Revert "Add Docker fiels for xds example server and client."
kannanjgithub Jun 26, 2025
d816b8e
Changes
kannanjgithub Jun 27, 2025
c8eca59
whitespace changes nightmares
kannanjgithub Jun 27, 2025
4b92066
whitespace changes nightmares
kannanjgithub Jun 27, 2025
3867cc7
whitespace changes nightmares
kannanjgithub Jun 27, 2025
c4bfaa5
Replace clusters array with single cluster in ClusterResolverLB
kannanjgithub Jun 30, 2025
400b776
Review comments, excepting the child cluster type change handling.
kannanjgithub Jul 9, 2025
fa21404
nit
kannanjgithub Jul 9, 2025
084c51c
Handle cluster type changes by using Graceful switch load balancer as…
kannanjgithub Jul 11, 2025
f2bfa63
Fix test
kannanjgithub Jul 11, 2025
7abbc4a
Review comments.
kannanjgithub Jul 18, 2025
7c16de8
Revert indendation changes done by IDE in unchanged lines.
kannanjgithub Jul 18, 2025
f6afb63
A map for ClusterState is not required in ClusterResolverLoadBalancer…
kannanjgithub Jul 22, 2025
e2a7382
Reinstantiate delegate after shutdown.
kannanjgithub Jul 29, 2025
ecb6b03
Merge branch 'master' into a75-fixes2
kannanjgithub Jul 29, 2025
8c1199d
Fix problem after merge.
kannanjgithub Jul 29, 2025
24910d8
Fix problem after merge.
kannanjgithub Jul 29, 2025
6c75018
Fix style errors.
kannanjgithub Jul 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 64 additions & 68 deletions xds/src/main/java/io/grpc/xds/CdsLoadBalancer2.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@

import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.ConnectivityState.TRANSIENT_FAILURE;
import static io.grpc.xds.XdsLbPolicies.CDS_POLICY_NAME;
import static io.grpc.xds.XdsLbPolicies.CLUSTER_RESOLVER_POLICY_NAME;
import static io.grpc.xds.XdsLbPolicies.PRIORITY_POLICY_NAME;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CheckReturnValue;
import io.grpc.InternalLogId;
import io.grpc.LoadBalancer;
import io.grpc.LoadBalancerProvider;
import io.grpc.LoadBalancerRegistry;
import io.grpc.NameResolver;
import io.grpc.Status;
Expand All @@ -33,6 +36,7 @@
import io.grpc.xds.CdsLoadBalancerProvider.CdsConfig;
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig;
import io.grpc.xds.ClusterResolverLoadBalancerProvider.ClusterResolverConfig.DiscoveryMechanism;
import io.grpc.xds.PriorityLoadBalancerProvider.PriorityLbConfig.PriorityChildConfig;
import io.grpc.xds.XdsClusterResource.CdsUpdate;
import io.grpc.xds.XdsClusterResource.CdsUpdate.ClusterType;
import io.grpc.xds.XdsConfig.Subscription;
Expand All @@ -41,10 +45,10 @@
import io.grpc.xds.XdsConfig.XdsClusterConfig.EndpointConfig;
import io.grpc.xds.client.XdsLogger;
import io.grpc.xds.client.XdsLogger.XdsLogLevel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

/**
* Load balancer for cds_experimental LB policy. One instance per top-level cluster.
Expand Down Expand Up @@ -91,7 +95,7 @@ public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
if (clusterSubscription == null) {
// Should be impossible, because XdsDependencyManager wouldn't have generated this
return fail(Status.INTERNAL.withDescription(
errorPrefix() + "Unable to find non-dynamic root cluster"));
errorPrefix() + "Unable to find non-dynamic cluster"));
}
// The dynamic cluster must not have loaded yet
return Status.OK;
Expand All @@ -100,82 +104,74 @@ public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
return fail(clusterConfigOr.getStatus());
}
XdsClusterConfig clusterConfig = clusterConfigOr.getValue();
List<String> leafNames;
if (clusterConfig.getChildren() instanceof AggregateConfig) {
leafNames = ((AggregateConfig) clusterConfig.getChildren()).getLeafNames();
} else if (clusterConfig.getChildren() instanceof EndpointConfig) {
leafNames = ImmutableList.of(clusterName);
} else {
return fail(Status.INTERNAL.withDescription(
errorPrefix() + "Unexpected cluster children type: "
+ clusterConfig.getChildren().getClass()));
}
if (leafNames.isEmpty()) {
// Should be impossible, because XdsClusterResource validated this
return fail(Status.UNAVAILABLE.withDescription(
errorPrefix() + "Zero leaf clusters for root cluster " + clusterName));
}

Status noneFoundError = Status.INTERNAL
.withDescription(errorPrefix() + "No leaves and no error; this is a bug");
List<DiscoveryMechanism> instances = new ArrayList<>();
for (String leafName : leafNames) {
StatusOr<XdsClusterConfig> leafConfigOr = xdsConfig.getClusters().get(leafName);
if (!leafConfigOr.hasValue()) {
noneFoundError = leafConfigOr.getStatus();
continue;
}
if (!(leafConfigOr.getValue().getChildren() instanceof EndpointConfig)) {
noneFoundError = Status.INTERNAL.withDescription(
errorPrefix() + "Unexpected child " + leafName + " cluster children type: "
+ leafConfigOr.getValue().getChildren().getClass());
continue;
NameResolver.ConfigOrError configOrError;
Object childConfig;
if (clusterConfig.getChildren() instanceof EndpointConfig) {
// The LB policy config is provided in service_config.proto/JSON format.
configOrError =
GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
Arrays.asList(clusterConfig.getClusterResource().lbPolicyConfig()),
lbRegistry);
if (configOrError.getError() != null) {
// Should be impossible, because XdsClusterResource validated this
return fail(Status.INTERNAL.withDescription(
errorPrefix() + "Unable to parse the LB config: " + configOrError.getError()));
}
CdsUpdate result = leafConfigOr.getValue().getClusterResource();
CdsUpdate result = clusterConfig.getClusterResource();
DiscoveryMechanism instance;
if (result.clusterType() == ClusterType.EDS) {
instance = DiscoveryMechanism.forEds(
leafName,
result.edsServiceName(),
result.lrsServerInfo(),
result.maxConcurrentRequests(),
result.upstreamTlsContext(),
result.filterMetadata(),
result.outlierDetection());
clusterName,
result.edsServiceName(),
result.lrsServerInfo(),
result.maxConcurrentRequests(),
result.upstreamTlsContext(),
result.filterMetadata(),
result.outlierDetection());
} else {
instance = DiscoveryMechanism.forLogicalDns(
leafName,
result.dnsHostName(),
result.lrsServerInfo(),
result.maxConcurrentRequests(),
result.upstreamTlsContext(),
result.filterMetadata());
clusterName,
result.dnsHostName(),
result.lrsServerInfo(),
result.maxConcurrentRequests(),
result.upstreamTlsContext(),
result.filterMetadata());
}
instances.add(instance);
}
if (instances.isEmpty()) {
return fail(noneFoundError);
}

// The LB policy config is provided in service_config.proto/JSON format.
NameResolver.ConfigOrError configOrError =
GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(
Arrays.asList(clusterConfig.getClusterResource().lbPolicyConfig()), lbRegistry);
if (configOrError.getError() != null) {
// Should be impossible, because XdsClusterResource validated this
childConfig = new ClusterResolverConfig(
instance,
configOrError.getConfig(),
clusterConfig.getClusterResource().isHttp11ProxyAvailable());
if (childLb == null) {
childLb = lbRegistry.getProvider(CLUSTER_RESOLVER_POLICY_NAME).newLoadBalancer(helper);
}
} else if (clusterConfig.getChildren() instanceof AggregateConfig) {
LoadBalancerProvider priorityLbProvider = lbRegistry.getProvider(PRIORITY_POLICY_NAME);
if (childLb == null) {
childLb = priorityLbProvider.newLoadBalancer(helper);
}
Map<String, PriorityChildConfig> priorityChildConfigs = new HashMap<>();
for (String childCluster: requireNonNull(
clusterConfig.getClusterResource().prioritizedClusterNames())) {
priorityChildConfigs.put(childCluster,
new PriorityChildConfig(
GracefulSwitchLoadBalancer.createLoadBalancingPolicyConfig(
lbRegistry.getProvider(CDS_POLICY_NAME),
new CdsConfig(childCluster)),
false));
}
childConfig = new PriorityLoadBalancerProvider.PriorityLbConfig(
Collections.unmodifiableMap(priorityChildConfigs),
Collections.unmodifiableList(requireNonNull(
clusterConfig.getClusterResource().prioritizedClusterNames())));
} else {
return fail(Status.INTERNAL.withDescription(
errorPrefix() + "Unable to parse the LB config: " + configOrError.getError()));
errorPrefix() + "Unexpected cluster children type: "
+ clusterConfig.getChildren().getClass()));
}

ClusterResolverConfig config = new ClusterResolverConfig(
Collections.unmodifiableList(instances),
configOrError.getConfig(),
clusterConfig.getClusterResource().isHttp11ProxyAvailable());
if (childLb == null) {
childLb = lbRegistry.getProvider(CLUSTER_RESOLVER_POLICY_NAME).newLoadBalancer(helper);
}
return childLb.acceptResolvedAddresses(
resolvedAddresses.toBuilder().setLoadBalancingPolicyConfig(config).build());
resolvedAddresses.toBuilder().setLoadBalancingPolicyConfig(childConfig).build());
}

@Override
Expand Down
29 changes: 14 additions & 15 deletions xds/src/main/java/io/grpc/xds/ClusterResolverLoadBalancer.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,20 @@ public Status acceptResolvedAddresses(ResolvedAddresses resolvedAddresses) {
ClusterResolverConfig config =
(ClusterResolverConfig) resolvedAddresses.getLoadBalancingPolicyConfig();
endpointLbConfig = config.lbConfig;
for (DiscoveryMechanism instance : config.discoveryMechanisms) {
clusters.add(instance.cluster);
ClusterState state;
if (instance.type == DiscoveryMechanism.Type.EDS) {
state = new EdsClusterState(instance.cluster, instance.edsServiceName,
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
instance.filterMetadata, instance.outlierDetection);
} else { // logical DNS
state = new LogicalDnsClusterState(instance.cluster, instance.dnsHostName,
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
instance.filterMetadata);
}
clusterStates.put(instance.cluster, state);
state.start();
}
DiscoveryMechanism instance = config.discoveryMechanism;
clusters.add(instance.cluster);
ClusterState state;
if (instance.type == DiscoveryMechanism.Type.EDS) {
state = new EdsClusterState(instance.cluster, instance.edsServiceName,
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
instance.filterMetadata, instance.outlierDetection);
} else { // logical DNS
state = new LogicalDnsClusterState(instance.cluster, instance.dnsHostName,
instance.lrsServerInfo, instance.maxConcurrentRequests, instance.tlsContext,
instance.filterMetadata);
}
clusterStates.put(instance.cluster, state);
state.start();
return Status.OK;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import io.grpc.xds.EnvoyServerProtoData.OutlierDetection;
import io.grpc.xds.EnvoyServerProtoData.UpstreamTlsContext;
import io.grpc.xds.client.Bootstrapper.ServerInfo;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -70,15 +69,15 @@ public LoadBalancer newLoadBalancer(Helper helper) {
}

static final class ClusterResolverConfig {
// Ordered list of clusters to be resolved.
final List<DiscoveryMechanism> discoveryMechanisms;
// Clusters to be resolved.
final DiscoveryMechanism discoveryMechanism;
// GracefulSwitch configuration
final Object lbConfig;
private final boolean isHttp11ProxyAvailable;

ClusterResolverConfig(List<DiscoveryMechanism> discoveryMechanisms, Object lbConfig,
boolean isHttp11ProxyAvailable) {
this.discoveryMechanisms = checkNotNull(discoveryMechanisms, "discoveryMechanisms");
ClusterResolverConfig(DiscoveryMechanism discoveryMechanism, Object lbConfig,
boolean isHttp11ProxyAvailable) {
this.discoveryMechanism = checkNotNull(discoveryMechanism, "discoveryMechanism");
this.lbConfig = checkNotNull(lbConfig, "lbConfig");
this.isHttp11ProxyAvailable = isHttp11ProxyAvailable;
}
Expand All @@ -89,7 +88,7 @@ boolean isHttp11ProxyAvailable() {

@Override
public int hashCode() {
return Objects.hash(discoveryMechanisms, lbConfig);
return Objects.hash(discoveryMechanism, lbConfig);
}

@Override
Expand All @@ -101,14 +100,14 @@ public boolean equals(Object o) {
return false;
}
ClusterResolverConfig that = (ClusterResolverConfig) o;
return discoveryMechanisms.equals(that.discoveryMechanisms)
return discoveryMechanism.equals(that.discoveryMechanism)
&& lbConfig.equals(that.lbConfig);
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("discoveryMechanisms", discoveryMechanisms)
.add("discoveryMechanism", discoveryMechanism)
.add("lbConfig", lbConfig)
.toString();
}
Expand Down
Loading
Loading