@@ -136,7 +136,9 @@ interface ClusterGraph {
136
136
[ name : string ] : ClusterEntry ;
137
137
}
138
138
139
- function isClusterTreeFullyUpdated ( tree : ClusterGraph , roots : string [ ] ) : boolean {
139
+ type ClusterTreeUpdatedResult = { result : true } | { result : false , reason : string } ;
140
+
141
+ function isClusterTreeFullyUpdated ( tree : ClusterGraph , roots : string [ ] ) : ClusterTreeUpdatedResult {
140
142
const toCheck : string [ ] = [ ...roots ] ;
141
143
const visited = new Set < string > ( ) ;
142
144
while ( toCheck . length > 0 ) {
@@ -145,19 +147,31 @@ function isClusterTreeFullyUpdated(tree: ClusterGraph, roots: string[]): boolean
145
147
continue ;
146
148
}
147
149
visited . add ( next ) ;
148
- if ( ! tree [ next ] || ! tree [ next ] . latestUpdate ) {
149
- return false ;
150
+ if ( ! tree [ next ] ) {
151
+ return {
152
+ result : false ,
153
+ reason : 'Missing expected cluster entry ' + next
154
+ } ;
155
+ }
156
+ if ( ! tree [ next ] . latestUpdate ) {
157
+ return {
158
+ result : false ,
159
+ reason : 'Cluster entry ' + next + ' not updated'
160
+ } ;
150
161
}
151
162
if ( tree [ next ] . latestUpdate . success ) {
152
163
if ( tree [ next ] . latestUpdate . value . type !== 'AGGREGATE' ) {
153
- if ( ! ( tree [ next ] . latestUpdate . value . latestUpdate || tree [ next ] . latestUpdate . value . latestUpdate ) ) {
154
- return false ;
164
+ if ( ! ( tree [ next ] . latestUpdate . value . latestUpdate ) ) {
165
+ return {
166
+ result : false ,
167
+ reason : 'Cluster entry ' + next + ' endpoint not updated'
168
+ } ;
155
169
}
156
170
}
157
171
}
158
172
toCheck . push ( ...tree [ next ] . children ) ;
159
173
}
160
- return true ;
174
+ return { result : true } ;
161
175
}
162
176
163
177
// Better match type has smaller value.
@@ -353,18 +367,21 @@ export class XdsDependencyManager {
353
367
const routeConfigName = httpConnectionManager . rds ! . route_config_name ;
354
368
if ( this . latestRouteConfigName !== routeConfigName ) {
355
369
if ( this . latestRouteConfigName !== null ) {
370
+ this . trace ( 'RDS.cancelWatch(' + this . latestRouteConfigName + '): Route config name changed' ) ;
356
371
RouteConfigurationResourceType . cancelWatch ( this . xdsClient , this . latestRouteConfigName , this . rdsWatcher ) ;
357
372
this . latestRouteConfiguration = null ;
358
373
this . clusterRoots = [ ] ;
359
374
this . pruneOrphanClusters ( ) ;
360
375
}
376
+ this . trace ( 'RDS.startWatch(' + routeConfigName + '): New route config name' ) ;
361
377
RouteConfigurationResourceType . startWatch ( this . xdsClient , routeConfigName , this . rdsWatcher ) ;
362
378
this . latestRouteConfigName = routeConfigName ;
363
379
}
364
380
break ;
365
381
}
366
382
case 'route_config' :
367
383
if ( this . latestRouteConfigName ) {
384
+ this . trace ( 'RDS.cancelWatch(' + this . latestRouteConfigName + '): Listener switched to embedded route config' ) ;
368
385
RouteConfigurationResourceType . cancelWatch ( this . xdsClient , this . latestRouteConfigName , this . rdsWatcher ) ;
369
386
this . latestRouteConfigName = null ;
370
387
}
@@ -378,13 +395,14 @@ export class XdsDependencyManager {
378
395
/* A transient error only needs to bubble up as a failure if we have
379
396
* not already provided a ServiceConfig for the upper layer to use */
380
397
if ( ! this . latestListener ) {
381
- trace ( 'Resolution error for target ' + listenerResourceName + ' due to xDS client transient error ' + error . details ) ;
398
+ this . trace ( 'Resolution error due to xDS client transient error ' + error . details ) ;
382
399
this . watcher . onError ( `Listener ${ listenerResourceName } ` , error ) ;
383
400
}
384
401
} ,
385
402
onResourceDoesNotExist : ( ) => {
386
- trace ( 'Resolution error for target ' + listenerResourceName + ' : LDS resource does not exist') ;
403
+ this . trace ( 'Resolution error: LDS resource does not exist' ) ;
387
404
if ( this . latestRouteConfigName ) {
405
+ this . trace ( 'RDS.cancelWatch(' + this . latestRouteConfigName + '): LDS resource does not exist' ) ;
388
406
RouteConfigurationResourceType . cancelWatch ( this . xdsClient , this . latestRouteConfigName , this . rdsWatcher ) ;
389
407
this . latestRouteConfigName = null ;
390
408
this . latestRouteConfiguration = null ;
@@ -409,11 +427,26 @@ export class XdsDependencyManager {
409
427
this . pruneOrphanClusters ( ) ;
410
428
}
411
429
} ) ;
430
+ this . trace ( 'LDS.startWatch(' + listenerResourceName + '): Startup' ) ;
412
431
ListenerResourceType . startWatch ( this . xdsClient , listenerResourceName , this . ldsWatcher ) ;
413
432
}
414
433
434
+ private trace ( text : string ) {
435
+ trace ( '[' + this . listenerResourceName + '] ' + text ) ;
436
+ }
437
+
415
438
private maybeSendUpdate ( ) {
416
- if ( ! ( this . latestListener && this . latestRouteConfiguration && isClusterTreeFullyUpdated ( this . clusterForest , this . clusterRoots ) ) ) {
439
+ if ( ! this . latestListener ) {
440
+ this . trace ( 'Not sending update: no Listener update received' ) ;
441
+ return ;
442
+ }
443
+ if ( ! this . latestRouteConfiguration ) {
444
+ this . trace ( 'Not sending update: no RouteConfiguration update received' ) ;
445
+ return ;
446
+ }
447
+ const clusterTreeUpdated = isClusterTreeFullyUpdated ( this . clusterForest , this . clusterRoots ) ;
448
+ if ( ! clusterTreeUpdated . result ) {
449
+ this . trace ( 'Not sending update: ' + clusterTreeUpdated . reason ) ;
417
450
return ;
418
451
}
419
452
const update : XdsConfig = {
@@ -424,6 +457,7 @@ export class XdsDependencyManager {
424
457
} ;
425
458
for ( const [ clusterName , entry ] of Object . entries ( this . clusterForest ) ) {
426
459
if ( ! entry . latestUpdate ) {
460
+ this . trace ( 'Not sending update: Cluster entry ' + clusterName + ' not updated (not caught by isClusterTreeFullyUpdated)' ) ;
427
461
return ;
428
462
}
429
463
if ( entry . latestUpdate . success ) {
@@ -471,6 +505,7 @@ export class XdsDependencyManager {
471
505
case 'AGGREGATE' :
472
506
break ;
473
507
case 'EDS' :
508
+ this . trace ( 'EDS.cancelWatch(' + entry . latestUpdate . value . edsServiceName + '): Cluster switched to aggregate' ) ;
474
509
EndpointResourceType . cancelWatch ( this . xdsClient , entry . latestUpdate . value . edsServiceName , entry . latestUpdate . value . watcher ) ;
475
510
break ;
476
511
case 'LOGICAL_DNS' :
@@ -503,7 +538,9 @@ export class XdsDependencyManager {
503
538
case 'EDS' :
504
539
// If the names are the same, keep the watch
505
540
if ( entry . latestUpdate . value . edsServiceName !== edsServiceName ) {
541
+ this . trace ( 'EDS.cancelWatch(' + entry . latestUpdate . value . edsServiceName + '): EDS service name changed' ) ;
506
542
EndpointResourceType . cancelWatch ( this . xdsClient , entry . latestUpdate . value . edsServiceName , entry . latestUpdate . value . watcher ) ;
543
+ this . trace ( 'EDS.startWatch(' + edsServiceName + '): EDS service name changed' ) ;
507
544
EndpointResourceType . startWatch ( this . xdsClient , edsServiceName , entry . latestUpdate . value . watcher ) ;
508
545
entry . latestUpdate . value . edsServiceName = edsServiceName ;
509
546
entry . latestUpdate . value . latestUpdate = undefined ;
@@ -550,6 +587,7 @@ export class XdsDependencyManager {
550
587
watcher : edsWatcher
551
588
}
552
589
} ;
590
+ this . trace ( 'EDS.startWatch(' + edsServiceName + '): New EDS service name' ) ;
553
591
EndpointResourceType . startWatch ( this . xdsClient , edsServiceName , edsWatcher ) ;
554
592
this . maybeSendUpdate ( ) ;
555
593
break ;
@@ -561,6 +599,7 @@ export class XdsDependencyManager {
561
599
this . pruneOrphanClusters ( ) ;
562
600
break ;
563
601
case 'EDS' :
602
+ this . trace ( 'EDS.cancelWatch(' + entry . latestUpdate . value . edsServiceName + '): Cluster switched to DNS' ) ;
564
603
EndpointResourceType . cancelWatch ( this . xdsClient , entry . latestUpdate . value . edsServiceName , entry . latestUpdate . value . watcher ) ;
565
604
break ;
566
605
case 'LOGICAL_DNS' :
@@ -571,7 +610,7 @@ export class XdsDependencyManager {
571
610
}
572
611
}
573
612
}
574
- trace ( 'Creating DNS resolver' ) ;
613
+ this . trace ( 'Creating DNS resolver for hostname ' + update . dnsHostname ! ) ;
575
614
const resolver = createResolver ( { scheme : 'dns' , path : update . dnsHostname ! } , {
576
615
onSuccessfulResolution : endpointList => {
577
616
if ( entry . latestUpdate ?. success && entry . latestUpdate . value . type === 'LOGICAL_DNS' ) {
@@ -616,6 +655,7 @@ export class XdsDependencyManager {
616
655
if ( entry . latestUpdate ?. success ) {
617
656
switch ( entry . latestUpdate . value . type ) {
618
657
case 'EDS' :
658
+ this . trace ( 'EDS.cancelWatch(' + entry . latestUpdate . value . edsServiceName + '): CDS resource does not exist' ) ;
619
659
EndpointResourceType . cancelWatch ( this . xdsClient , entry . latestUpdate . value . edsServiceName , entry . latestUpdate . value . watcher ) ;
620
660
break ;
621
661
case 'LOGICAL_DNS' :
@@ -639,6 +679,7 @@ export class XdsDependencyManager {
639
679
children : [ ]
640
680
}
641
681
this . clusterForest [ clusterName ] = entry ;
682
+ this . trace ( 'CDS.startWatch(' + clusterName + '): Cluster added' ) ;
642
683
ClusterResourceType . startWatch ( this . xdsClient , clusterName , entry . watcher ) ;
643
684
}
644
685
@@ -670,6 +711,7 @@ export class XdsDependencyManager {
670
711
if ( entry . latestUpdate ?. success ) {
671
712
switch ( entry . latestUpdate . value . type ) {
672
713
case 'EDS' :
714
+ this . trace ( 'EDS.cancelWatch(' + entry . latestUpdate . value . edsServiceName + '): Cluster ' + clusterName + ' removed' ) ;
673
715
EndpointResourceType . cancelWatch ( this . xdsClient , entry . latestUpdate . value . edsServiceName , entry . latestUpdate . value . watcher ) ;
674
716
break ;
675
717
case 'LOGICAL_DNS' :
@@ -679,6 +721,7 @@ export class XdsDependencyManager {
679
721
break ;
680
722
}
681
723
}
724
+ this . trace ( 'CDS.cancelWatch(' + clusterName + '): Cluster removed' ) ;
682
725
ClusterResourceType . cancelWatch ( this . xdsClient , clusterName , entry . watcher ) ;
683
726
delete this . clusterForest [ clusterName ] ;
684
727
}
@@ -761,8 +804,10 @@ export class XdsDependencyManager {
761
804
}
762
805
763
806
destroy ( ) {
807
+ this . trace ( 'LDS.cancelWatch(' + this . listenerResourceName + '): destroy' ) ;
764
808
ListenerResourceType . cancelWatch ( this . xdsClient , this . listenerResourceName , this . ldsWatcher ) ;
765
809
if ( this . latestRouteConfigName ) {
810
+ this . trace ( 'RDS.cancelWatch(' + this . latestRouteConfigName + '): destroy' ) ;
766
811
RouteConfigurationResourceType . cancelWatch ( this . xdsClient , this . latestRouteConfigName , this . rdsWatcher ) ;
767
812
}
768
813
this . clusterRoots = [ ] ;
0 commit comments