Skip to content

Commit 6c12c2b

Browse files
committedJan 6, 2025·
xds: Remember nonces for unknown types
If the control plane sends a resource type the client doesn't understand at-the-moment, the control plane will still expect the client to include the nonce if the client subscribes to the type in the future. This most easily happens when unsubscribing the last resource of a type. Which meant 1cf1927 was insufficient.
1 parent 4a0f707 commit 6c12c2b

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed
 

‎xds/src/main/java/io/grpc/xds/client/ControlPlaneClient.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ private class AdsStream implements XdsTransportFactory.EventHandler<DiscoveryRes
309309
private boolean responseReceived;
310310
private boolean sentInitialRequest;
311311
private boolean closed;
312-
// Response nonce for the most recently received discovery responses of each resource type.
312+
// Response nonce for the most recently received discovery responses of each resource type URL.
313313
// Client initiated requests start response nonce with empty string.
314314
// Nonce in each response is echoed back in the following ACK/NACK request. It is
315315
// used for management server to identify which response the client is ACKing/NACking.
@@ -318,7 +318,7 @@ private class AdsStream implements XdsTransportFactory.EventHandler<DiscoveryRes
318318
// map; nonces are only discarded once the stream closes because xds_protocol says "the
319319
// management server should not send a DiscoveryResponse for any DiscoveryRequest that has a
320320
// stale nonce."
321-
private final Map<XdsResourceType<?>, String> respNonces = new HashMap<>();
321+
private final Map<String, String> respNonces = new HashMap<>();
322322
private final StreamingCall<DiscoveryRequest, DiscoveryResponse> call;
323323
private final MethodDescriptor<DiscoveryRequest, DiscoveryResponse> methodDescriptor =
324324
AggregatedDiscoveryServiceGrpc.getStreamAggregatedResourcesMethod();
@@ -369,7 +369,7 @@ void sendDiscoveryRequest(XdsResourceType<?> type, String versionInfo,
369369
final void sendDiscoveryRequest(XdsResourceType<?> type, Collection<String> resources) {
370370
logger.log(XdsLogLevel.INFO, "Sending {0} request for resources: {1}", type, resources);
371371
sendDiscoveryRequest(type, versions.getOrDefault(type, ""), resources,
372-
respNonces.getOrDefault(type, ""), null);
372+
respNonces.getOrDefault(type.typeUrl(), ""), null);
373373
}
374374

375375
@Override
@@ -400,6 +400,7 @@ public void run() {
400400
boolean isFirstResponse = !responseReceived;
401401
responseReceived = true;
402402
inError = false;
403+
respNonces.put(response.getTypeUrl(), response.getNonce());
403404

404405
XdsResourceType<?> type = fromTypeUrl(response.getTypeUrl());
405406
if (logger.isLoggable(XdsLogLevel.DEBUG)) {
@@ -433,7 +434,6 @@ final void handleRpcResponse(XdsResourceType<?> type, String versionInfo, List<A
433434
String nonce, boolean isFirstResponse) {
434435
checkNotNull(type, "type");
435436

436-
respNonces.put(type, nonce);
437437
ProcessingTracker processingTracker = new ProcessingTracker(
438438
() -> call.startRecvMessage(), syncContext);
439439
xdsResponseHandler.handleResourceResponse(type, serverInfo, versionInfo, resources, nonce,

‎xds/src/test/java/io/grpc/xds/GrpcXdsClientImplTestBase.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -2898,10 +2898,13 @@ public void edsCleanupNonceAfterUnsubscription() {
28982898
xdsClient.cancelXdsResourceWatch(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
28992899
verifySubscribedResourcesMetadataSizes(0, 0, 0, 0);
29002900
call.verifyRequest(EDS, Arrays.asList(), VERSION_1, "0000", NODE);
2901+
// The control plane can send an updated response for the empty subscription list, with a new
2902+
// nonce.
2903+
call.sendResponse(EDS, Arrays.asList(), VERSION_1, "0001");
29012904

29022905
// When re-subscribing, the version was forgotten but not the nonce
29032906
xdsClient.watchXdsResource(XdsEndpointResource.getInstance(), "A.1", edsResourceWatcher);
2904-
call.verifyRequest(EDS, "A.1", "", "0000", NODE, Mockito.timeout(2000));
2907+
call.verifyRequest(EDS, "A.1", "", "0001", NODE, Mockito.timeout(2000));
29052908
}
29062909

29072910
@Test

0 commit comments

Comments
 (0)
Please sign in to comment.