xds: Preserve nonce when unsubscribing type

This fixes a regression introduced in 19c9b998.

b/374697875
This commit is contained in:
Eric Anderson 2025-01-03 12:34:47 -08:00 committed by GitHub
parent 9a712c3f77
commit 1cf1927d1a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 6 deletions

View File

@ -167,9 +167,10 @@ final class ControlPlaneClient {
resourceStore.startMissingResourceTimers(resources, resourceType); resourceStore.startMissingResourceTimers(resources, resourceType);
if (resources.isEmpty()) { if (resources.isEmpty()) {
// The resource type no longer has subscribing resources; clean up references to it // The resource type no longer has subscribing resources; clean up references to it, except
// for nonces. If the resource type becomes used again the control plane can ignore requests
// for old/missing nonces. Old type's nonces are dropped when the ADS stream is restarted.
versions.remove(resourceType); versions.remove(resourceType);
adsStream.respNonces.remove(resourceType);
} }
} }
@ -313,7 +314,10 @@ final class ControlPlaneClient {
// Nonce in each response is echoed back in the following ACK/NACK request. It is // Nonce in each response is echoed back in the following ACK/NACK request. It is
// used for management server to identify which response the client is ACKing/NACking. // used for management server to identify which response the client is ACKing/NACking.
// To avoid confusion, client-initiated requests will always use the nonce in // To avoid confusion, client-initiated requests will always use the nonce in
// most recently received responses of each resource type. // most recently received responses of each resource type. Nonces are never deleted from the
// map; nonces are only discarded once the stream closes because xds_protocol says "the
// management server should not send a DiscoveryResponse for any DiscoveryRequest that has a
// stale nonce."
private final Map<XdsResourceType<?>, String> respNonces = new HashMap<>(); private final Map<XdsResourceType<?>, String> respNonces = new HashMap<>();
private final StreamingCall<DiscoveryRequest, DiscoveryResponse> call; private final StreamingCall<DiscoveryRequest, DiscoveryResponse> call;
private final MethodDescriptor<DiscoveryRequest, DiscoveryResponse> methodDescriptor = private final MethodDescriptor<DiscoveryRequest, DiscoveryResponse> methodDescriptor =

View File

@ -2899,10 +2899,9 @@ public abstract class GrpcXdsClientImplTestBase {
verifySubscribedResourcesMetadataSizes(0, 0, 0, 0); verifySubscribedResourcesMetadataSizes(0, 0, 0, 0);
call.verifyRequest(EDS, Arrays.asList(), VERSION_1, "0000", NODE); call.verifyRequest(EDS, Arrays.asList(), VERSION_1, "0000", NODE);
// When re-subscribing, the version and nonce were properly forgotten, so the request is the // When re-subscribing, the version was forgotten but not the nonce
// same as the initial request
xdsClient.watchXdsResource(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher); xdsClient.watchXdsResource(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
call.verifyRequest(EDS, "A.1", "", "", NODE, Mockito.timeout(2000).times(2)); call.verifyRequest(EDS, "A.1", "", "0000", NODE, Mockito.timeout(2000));
} }
@Test @Test