Skip to content

Commit 15026d5

Browse files
authored
xds:fix cancel xds watcher accidentally removes the url (v1.52 backport) (#9810)
Fix a bug. When any of the subscribers for a resource has the last watcher cancelled, the bug will accidentally remove that resource type from the map, which make xds stream not accepting response update for that resource type entirely (pass through, no ACK/NACK will send).
1 parent a13a2dd commit 15026d5

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

xds/src/main/java/io/grpc/xds/XdsClientImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,13 @@ public void run() {
328328
if (!subscriber.isWatched()) {
329329
subscriber.cancelResourceWatch();
330330
resourceSubscribers.get(type).remove(resourceName);
331-
subscribedResourceTypeUrls.remove(type.typeUrl());
332-
subscribedResourceTypeUrls.remove(type.typeUrlV2());
333331
if (subscriber.xdsChannel != null) {
334332
subscriber.xdsChannel.adjustResourceSubscription(type);
335333
}
336334
if (resourceSubscribers.get(type).isEmpty()) {
337335
resourceSubscribers.remove(type);
336+
subscribedResourceTypeUrls.remove(type.typeUrl());
337+
subscribedResourceTypeUrls.remove(type.typeUrlV2());
338338
}
339339
}
340340
}

xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,35 @@ public void ldsResourceUpdated() {
921921
assertThat(channelForEmptyAuthority).isNull();
922922
}
923923

924+
@Test
925+
public void cancelResourceWatcherNotRemoveUrlSubscribers() {
926+
DiscoveryRpcCall call = startResourceWatcher(XdsListenerResource.getInstance(), LDS_RESOURCE,
927+
ldsResourceWatcher);
928+
verifyResourceMetadataRequested(LDS, LDS_RESOURCE);
929+
930+
// Initial LDS response.
931+
call.sendResponse(LDS, testListenerVhosts, VERSION_1, "0000");
932+
call.verifyRequest(LDS, LDS_RESOURCE, VERSION_1, "0000", NODE);
933+
verify(ldsResourceWatcher).onChanged(ldsUpdateCaptor.capture());
934+
verifyGoldenListenerVhosts(ldsUpdateCaptor.getValue());
935+
verifyResourceMetadataAcked(LDS, LDS_RESOURCE, testListenerVhosts, VERSION_1, TIME_INCREMENT);
936+
937+
xdsClient.watchXdsResource(XdsListenerResource.getInstance(),
938+
LDS_RESOURCE + "1", ldsResourceWatcher);
939+
xdsClient.cancelXdsResourceWatch(XdsListenerResource.getInstance(), LDS_RESOURCE + "1",
940+
ldsResourceWatcher);
941+
942+
// Updated LDS response.
943+
Any testListenerVhosts2 = Any.pack(mf.buildListenerWithApiListener(LDS_RESOURCE,
944+
mf.buildRouteConfiguration("new", mf.buildOpaqueVirtualHosts(VHOST_SIZE))));
945+
call.sendResponse(LDS, testListenerVhosts2, VERSION_2, "0001");
946+
call.verifyRequest(LDS, LDS_RESOURCE, VERSION_2, "0001", NODE);
947+
verify(ldsResourceWatcher).onChanged(ldsUpdateCaptor.capture());
948+
verifyGoldenListenerVhosts(ldsUpdateCaptor.getValue());
949+
verifyResourceMetadataAcked(LDS, LDS_RESOURCE, testListenerVhosts2, VERSION_2,
950+
TIME_INCREMENT * 2);
951+
}
952+
924953
@Test
925954
public void ldsResourceUpdated_withXdstpResourceName() {
926955
BootstrapperImpl.enableFederation = true;

0 commit comments

Comments
 (0)