Skip to content

Commit

Permalink
xds:fix cancel xds watcher accidentally removes the url (v1.52 backpo…
Browse files Browse the repository at this point in the history
…rt) (#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).
  • Loading branch information
YifeiZhuang authored Jan 12, 2023
1 parent a13a2dd commit 15026d5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
4 changes: 2 additions & 2 deletions xds/src/main/java/io/grpc/xds/XdsClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -328,13 +328,13 @@ public void run() {
if (!subscriber.isWatched()) {
subscriber.cancelResourceWatch();
resourceSubscribers.get(type).remove(resourceName);
subscribedResourceTypeUrls.remove(type.typeUrl());
subscribedResourceTypeUrls.remove(type.typeUrlV2());
if (subscriber.xdsChannel != null) {
subscriber.xdsChannel.adjustResourceSubscription(type);
}
if (resourceSubscribers.get(type).isEmpty()) {
resourceSubscribers.remove(type);
subscribedResourceTypeUrls.remove(type.typeUrl());
subscribedResourceTypeUrls.remove(type.typeUrlV2());
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions xds/src/test/java/io/grpc/xds/XdsClientImplTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,35 @@ public void ldsResourceUpdated() {
assertThat(channelForEmptyAuthority).isNull();
}

@Test
public void cancelResourceWatcherNotRemoveUrlSubscribers() {
DiscoveryRpcCall call = startResourceWatcher(XdsListenerResource.getInstance(), LDS_RESOURCE,
ldsResourceWatcher);
verifyResourceMetadataRequested(LDS, LDS_RESOURCE);

// Initial LDS response.
call.sendResponse(LDS, testListenerVhosts, VERSION_1, "0000");
call.verifyRequest(LDS, LDS_RESOURCE, VERSION_1, "0000", NODE);
verify(ldsResourceWatcher).onChanged(ldsUpdateCaptor.capture());
verifyGoldenListenerVhosts(ldsUpdateCaptor.getValue());
verifyResourceMetadataAcked(LDS, LDS_RESOURCE, testListenerVhosts, VERSION_1, TIME_INCREMENT);

xdsClient.watchXdsResource(XdsListenerResource.getInstance(),
LDS_RESOURCE + "1", ldsResourceWatcher);
xdsClient.cancelXdsResourceWatch(XdsListenerResource.getInstance(), LDS_RESOURCE + "1",
ldsResourceWatcher);

// Updated LDS response.
Any testListenerVhosts2 = Any.pack(mf.buildListenerWithApiListener(LDS_RESOURCE,
mf.buildRouteConfiguration("new", mf.buildOpaqueVirtualHosts(VHOST_SIZE))));
call.sendResponse(LDS, testListenerVhosts2, VERSION_2, "0001");
call.verifyRequest(LDS, LDS_RESOURCE, VERSION_2, "0001", NODE);
verify(ldsResourceWatcher).onChanged(ldsUpdateCaptor.capture());
verifyGoldenListenerVhosts(ldsUpdateCaptor.getValue());
verifyResourceMetadataAcked(LDS, LDS_RESOURCE, testListenerVhosts2, VERSION_2,
TIME_INCREMENT * 2);
}

@Test
public void ldsResourceUpdated_withXdstpResourceName() {
BootstrapperImpl.enableFederation = true;
Expand Down

0 comments on commit 15026d5

Please sign in to comment.