@@ -144,7 +144,7 @@ private void shutdown() {
144144 }
145145 }
146146
147- private void handleClusterDiscovered2 () {
147+ private void handleClusterDiscovered () {
148148 if (root .isLeaf ) {
149149 DiscoveryMechanism instance ;
150150 if (root .result .clusterType () == ClusterType .EDS ) {
@@ -201,6 +201,8 @@ private void handleClusterDiscovered2() {
201201 continue ;
202202 }
203203 if (clusterState .isLeaf ) {
204+ numLeafClusters ++;
205+ } else {
204206 if (clusterState .childClusterStates == null ) {
205207 continue ;
206208 }
@@ -234,7 +236,7 @@ private void handleClusterDiscovered2() {
234236 return ;
235237 }
236238
237- if (instances . isEmpty () ) { // none of non-aggregate clusters exists
239+ if (numLeafClusters == 0 ) { // none of non-aggregate clusters exists
238240 if (childLb != null ) {
239241 childLb .shutdown ();
240242 childLb = null ;
@@ -271,115 +273,6 @@ private void handleClusterDiscovered2() {
271273 }
272274 }
273275
274- private void handleClusterDiscovered () {
275- List <DiscoveryMechanism > instances = new ArrayList <>();
276-
277- // Used for loop detection to break the infinite recursion that loops would cause
278- Map <ClusterState , List <ClusterState >> parentClusters = new HashMap <>();
279- Status loopStatus = null ;
280-
281- // Level-order traversal.
282- // Collect configurations for all non-aggregate (leaf) clusters.
283- Queue <ClusterState > queue = new ArrayDeque <>();
284- queue .add (root );
285- while (!queue .isEmpty ()) {
286- int size = queue .size ();
287- for (int i = 0 ; i < size ; i ++) {
288- ClusterState clusterState = queue .remove ();
289- if (!clusterState .discovered ) {
290- return ; // do not proceed until all clusters discovered
291- }
292- if (clusterState .result == null ) { // resource revoked or not exists
293- continue ;
294- }
295- if (clusterState .isLeaf ) {
296- if (instances .stream ().map (inst -> inst .cluster ).noneMatch (clusterState .name ::equals )) {
297- DiscoveryMechanism instance ;
298- if (clusterState .result .clusterType () == ClusterType .EDS ) {
299- instance = DiscoveryMechanism .forEds (
300- clusterState .name , clusterState .result .edsServiceName (),
301- clusterState .result .lrsServerInfo (),
302- clusterState .result .maxConcurrentRequests (),
303- clusterState .result .upstreamTlsContext (),
304- clusterState .result .filterMetadata (),
305- clusterState .result .outlierDetection ());
306- } else { // logical DNS
307- instance = DiscoveryMechanism .forLogicalDns (
308- clusterState .name , clusterState .result .dnsHostName (),
309- clusterState .result .lrsServerInfo (),
310- clusterState .result .maxConcurrentRequests (),
311- clusterState .result .upstreamTlsContext (),
312- clusterState .result .filterMetadata ());
313- }
314- instances .add (instance );
315- }
316- } else {
317- if (clusterState .childClusterStates == null ) {
318- continue ;
319- }
320- // Do loop detection and break recursion if detected
321- List <String > namesCausingLoops = identifyLoops (clusterState , parentClusters );
322- if (namesCausingLoops .isEmpty ()) {
323- queue .addAll (clusterState .childClusterStates .values ());
324- } else {
325- // Do cleanup
326- if (childLb != null ) {
327- childLb .shutdown ();
328- childLb = null ;
329- }
330- if (loopStatus != null ) {
331- logger .log (XdsLogLevel .WARNING ,
332- "Multiple loops in CDS config. Old msg: " + loopStatus .getDescription ());
333- }
334- loopStatus = Status .UNAVAILABLE .withDescription (String .format (
335- "CDS error: circular aggregate clusters directly under %s for "
336- + "root cluster %s, named %s, xDS node ID: %s" ,
337- clusterState .name , root .name , namesCausingLoops ,
338- xdsClient .getBootstrapInfo ().node ().getId ()));
339- }
340- }
341- }
342- }
343-
344- if (loopStatus != null ) {
345- helper .updateBalancingState (
346- TRANSIENT_FAILURE , new FixedResultPicker (PickResult .withError (loopStatus )));
347- return ;
348- }
349-
350- if (instances .isEmpty ()) { // none of non-aggregate clusters exists
351- if (childLb != null ) {
352- childLb .shutdown ();
353- childLb = null ;
354- }
355- Status unavailable = Status .UNAVAILABLE .withDescription (String .format (
356- "CDS error: found 0 leaf (logical DNS or EDS) clusters for root cluster %s"
357- + " xDS node ID: %s" , root .name , xdsClient .getBootstrapInfo ().node ().getId ()));
358- helper .updateBalancingState (
359- TRANSIENT_FAILURE , new FixedResultPicker (PickResult .withError (unavailable )));
360- return ;
361- }
362-
363- // The LB policy config is provided in service_config.proto/JSON format.
364- NameResolver .ConfigOrError configOrError =
365- GracefulSwitchLoadBalancer .parseLoadBalancingPolicyConfig (
366- Arrays .asList (root .result .lbPolicyConfig ()), lbRegistry );
367- if (configOrError .getError () != null ) {
368- throw configOrError .getError ().augmentDescription ("Unable to parse the LB config" )
369- .asRuntimeException ();
370- }
371-
372- ClusterResolverConfig config = new ClusterResolverConfig (
373- Collections .unmodifiableList (instances ),
374- configOrError .getConfig (),
375- root .result .isHttp11ProxyAvailable ());
376- if (childLb == null ) {
377- childLb = lbRegistry .getProvider (CLUSTER_RESOLVER_POLICY_NAME ).newLoadBalancer (helper );
378- }
379- childLb .handleResolvedAddresses (
380- resolvedAddresses .toBuilder ().setLoadBalancingPolicyConfig (config ).build ());
381- }
382-
383276 /**
384277 * Returns children that would cause loops and builds up the parentClusters map.
385278 **/
0 commit comments