From 27fe7a447b0ee61b5bb3380e1b1858b679b3fd9c Mon Sep 17 00:00:00 2001 From: MV Shiva Prasad Date: Thu, 7 Aug 2025 12:54:06 +0530 Subject: [PATCH 1/2] xds: xdsClient caches transient error for new watchers --- .../main/java/io/grpc/xds/client/XdsClientImpl.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java b/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java index d3384cbbe4e..bd5fcbfee00 100644 --- a/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java +++ b/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java @@ -676,6 +676,8 @@ private final class ResourceSubscriber { private ResourceMetadata metadata; @Nullable private String errorDescription; + @Nullable + private Status lastError; ResourceSubscriber(XdsResourceType type, String resource) { syncContext.throwIfNotInThisSynchronizationContext(); @@ -712,11 +714,16 @@ void addWatcher(ResourceWatcher watcher, Executor watcherExecutor) { watchers.put(watcher, watcherExecutor); T savedData = data; boolean savedAbsent = absent; + Status savedError = lastError; watcherExecutor.execute(() -> { if (errorDescription != null) { watcher.onError(Status.INVALID_ARGUMENT.withDescription(errorDescription)); return; } + if (savedError != null) { + watcher.onError(savedError); + return; + } if (savedData != null) { notifyWatcher(watcher, savedData); } else if (savedAbsent) { @@ -808,6 +815,7 @@ void onData(ParsedResource parsedResource, String version, long updateTime, this.metadata = ResourceMetadata .newResourceMetadataAcked(parsedResource.getRawResource(), version, updateTime); absent = false; + lastError = null; if (resourceDeletionIgnored) { logger.log(XdsLogLevel.FORCE_INFO, "xds server {0}: server returned new version " + "of resource for which we previously ignored a deletion: type {1} name {2}", @@ -857,6 +865,7 @@ void onAbsent(@Nullable ProcessingTracker processingTracker, ServerInfo serverIn if (!absent) { data = null; absent = true; + lastError = null; metadata = serverInfo.resourceTimerIsTransientError() ? ResourceMetadata.newResourceMetadataTimeout() : ResourceMetadata.newResourceMetadataDoesNotExist(); @@ -894,6 +903,9 @@ void onError(Status error, @Nullable ProcessingTracker tracker) { Status errorAugmented = Status.fromCode(error.getCode()) .withDescription(description + "nodeID: " + bootstrapInfo.node().getId()) .withCause(error.getCause()); + this.lastError = errorAugmented; + this.data = null; + this.absent = false; for (ResourceWatcher watcher : watchers.keySet()) { if (tracker != null) { From 033a4b10360e7bca9fe88f0613e3c8600cebf543 Mon Sep 17 00:00:00 2001 From: MV Shiva Prasad Date: Fri, 8 Aug 2025 21:09:12 +0530 Subject: [PATCH 2/2] address comments --- xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java b/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java index bd5fcbfee00..4c6823f844a 100644 --- a/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java +++ b/xds/src/main/java/io/grpc/xds/client/XdsClientImpl.java @@ -904,8 +904,6 @@ void onError(Status error, @Nullable ProcessingTracker tracker) { .withDescription(description + "nodeID: " + bootstrapInfo.node().getId()) .withCause(error.getCause()); this.lastError = errorAugmented; - this.data = null; - this.absent = false; for (ResourceWatcher watcher : watchers.keySet()) { if (tracker != null) {