@@ -93,13 +93,15 @@ public static String toContextStr(String typeName, String resourceName) {
93
93
94
94
@ Override
95
95
public Closeable subscribeToCluster (String clusterName ) {
96
-
97
96
checkNotNull (clusterName , "clusterName" );
98
97
ClusterSubscription subscription = new ClusterSubscription (clusterName );
99
98
100
99
syncContext .execute (() -> {
100
+ if (getWatchers (XdsListenerResource .getInstance ()).isEmpty ()) {
101
+ subscription .closed = true ;
102
+ return ; // shutdown() called
103
+ }
101
104
addClusterWatcher (clusterName , subscription , 1 );
102
- maybePublishConfig ();
103
105
});
104
106
105
107
return subscription ;
@@ -207,10 +209,14 @@ private void releaseSubscription(ClusterSubscription subscription) {
207
209
checkNotNull (subscription , "subscription" );
208
210
String clusterName = subscription .getClusterName ();
209
211
syncContext .execute (() -> {
212
+ if (subscription .closed ) {
213
+ return ;
214
+ }
215
+ subscription .closed = true ;
210
216
XdsWatcherBase <?> cdsWatcher =
211
217
resourceWatchers .get (CLUSTER_RESOURCE ).watchers .get (clusterName );
212
218
if (cdsWatcher == null ) {
213
- return ; // already released while waiting for the syncContext
219
+ return ; // shutdown() called
214
220
}
215
221
cancelClusterWatcherTree ((CdsWatcher ) cdsWatcher , subscription );
216
222
maybePublishConfig ();
@@ -257,6 +263,9 @@ private void cancelClusterWatcherTree(CdsWatcher root, Object parentContext) {
257
263
*/
258
264
private void maybePublishConfig () {
259
265
syncContext .throwIfNotInThisSynchronizationContext ();
266
+ if (getWatchers (XdsListenerResource .getInstance ()).isEmpty ()) {
267
+ return ; // shutdown() called
268
+ }
260
269
boolean waitingOnResource = resourceWatchers .values ().stream ()
261
270
.flatMap (typeWatchers -> typeWatchers .watchers .values ().stream ())
262
271
.anyMatch (XdsWatcherBase ::missingResult );
@@ -293,6 +302,11 @@ StatusOr<XdsConfig> buildUpdate() {
293
302
routeSource = ((LdsWatcher ) ldsWatcher ).getRouteSource ();
294
303
}
295
304
305
+ if (routeSource == null ) {
306
+ return StatusOr .fromStatus (Status .UNAVAILABLE .withDescription (
307
+ "Bug: No route source found for listener " + dataPlaneAuthority ));
308
+ }
309
+
296
310
StatusOr <RdsUpdate > statusOrRdsUpdate = routeSource .getRdsUpdate ();
297
311
if (!statusOrRdsUpdate .hasValue ()) {
298
312
return StatusOr .fromStatus (statusOrRdsUpdate .getStatus ());
@@ -557,14 +571,15 @@ public interface XdsConfigWatcher {
557
571
void onUpdate (StatusOr <XdsConfig > config );
558
572
}
559
573
560
- private class ClusterSubscription implements Closeable {
561
- String clusterName ;
574
+ private final class ClusterSubscription implements Closeable {
575
+ private final String clusterName ;
576
+ boolean closed ; // Accessed from syncContext
562
577
563
578
public ClusterSubscription (String clusterName ) {
564
- this .clusterName = clusterName ;
579
+ this .clusterName = checkNotNull ( clusterName , "clusterName" ) ;
565
580
}
566
581
567
- public String getClusterName () {
582
+ String getClusterName () {
568
583
return clusterName ;
569
584
}
570
585
0 commit comments