xds,googleapis: Allow wrapping NameResolver to inject XdsClient#12450
Merged
ejona86 merged 2 commits intogrpc:masterfrom Oct 29, 2025
Merged
xds,googleapis: Allow wrapping NameResolver to inject XdsClient#12450ejona86 merged 2 commits intogrpc:masterfrom
ejona86 merged 2 commits intogrpc:masterfrom
Conversation
1a23135 to
b49d940
Compare
Since there is no longer a single global XdsClient, it makes more sense to allow things like the c2p name resolver to inject its own bootstrap even if there is one defined in an environment variable. GoogleCloudToProdNameResolver can now pass an XdsClient instance to XdsNameResolver, and SharedXdsClientPoolProvider allows GoogleCloudToProdNameResolver to choose the bootstrap for that one specific target. Since XdsNameResolver is no longer in control of the XdsClient pool the XdsClient instance is now passed to ClusterImplLb. A channel will now only access the global XdsClient pool exactly once: in the name resolver. BootstrapInfo is purposefully being shared across channels, as we really want to share things like credentials which can have significant memory use and may have caches which reduce I/O when shared. That is why SharedXdsClientPoolProvider receives BootstrapInfo instead of Map<String,?>. Verifying BootstrapInfo.server() is not empty was moved from SharedXdsClientPoolProvider to GrpcBootstrapperImpl so avoid getOrCreate() throwing an exception in only that one case. It might make sense to move that to BootstrapperImpl, but that will need more investigation. A lot of tests needed updating because XdsClientPoolProvider is no longer responsible for parsing the bootstrap, so we now need bootstraps even if XdsClientPoolProvider will ignore it. This also fixes a bug in GoogleCloudToProdNameResolver where it would initialize the delegate even when it failed to create the bootstrap. That would certainly cause all RPCs on the channel to fail because of the missing bootstrap and it defeated the point of `succeeded == false` and `refresh()` which was supposed to retry contacting the metadata server. The server tests were enhanced to give a useful error when server.start() throws an exception, as otherwise the real error is lost.
b49d940 to
38f92fe
Compare
kannanjgithub
approved these changes
Oct 29, 2025
AgraVator
pushed a commit
to AgraVator/grpc-java
that referenced
this pull request
Nov 3, 2025
…#12450) Since there is no longer a single global XdsClient, it makes more sense to allow things like the c2p name resolver to inject its own bootstrap even if there is one defined in an environment variable. GoogleCloudToProdNameResolver can now pass an XdsClient instance to XdsNameResolver, and SharedXdsClientPoolProvider allows GoogleCloudToProdNameResolver to choose the bootstrap for that one specific target. Since XdsNameResolver is no longer in control of the XdsClient pool the XdsClient instance is now passed to ClusterImplLb. A channel will now only access the global XdsClient pool exactly once: in the name resolver. BootstrapInfo is purposefully being shared across channels, as we really want to share things like credentials which can have significant memory use and may have caches which reduce I/O when shared. That is why SharedXdsClientPoolProvider receives BootstrapInfo instead of Map<String,?>. Verifying BootstrapInfo.server() is not empty was moved from SharedXdsClientPoolProvider to GrpcBootstrapperImpl so avoid getOrCreate() throwing an exception in only that one case. It might make sense to move that to BootstrapperImpl, but that will need more investigation. A lot of tests needed updating because XdsClientPoolProvider is no longer responsible for parsing the bootstrap, so we now need bootstraps even if XdsClientPoolProvider will ignore it. This also fixes a bug in GoogleCloudToProdNameResolver where it would initialize the delegate even when it failed to create the bootstrap. That would certainly cause all RPCs on the channel to fail because of the missing bootstrap and it defeated the point of `succeeded == false` and `refresh()` which was supposed to retry contacting the metadata server. The server tests were enhanced to give a useful error when server.start() throws an exception, as otherwise the real error is lost. b/442819521
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since there is no longer a single global XdsClient, it makes more sense to allow things like the c2p name resolver to inject its own bootstrap even if there is one defined in an environment variable. GoogleCloudToProdNameResolver can now pass an XdsClient instance to XdsNameResolver, and SharedXdsClientPoolProvider allows GoogleCloudToProdNameResolver to choose the bootstrap for that one specific target.
Since XdsNameResolver is no longer in control of the XdsClient pool the XdsClient instance is now passed to ClusterImplLb. A channel will now only access the global XdsClient pool exactly once: in the name resolver.
BootstrapInfo is purposefully being shared across channels, as we really want to share things like credentials which can have significant memory use and may have caches which reduce I/O when shared. That is why SharedXdsClientPoolProvider receives BootstrapInfo instead of Map<String,?>.
Verifying BootstrapInfo.server() is not empty was moved from SharedXdsClientPoolProvider to GrpcBootstrapperImpl so avoid getOrCreate() throwing an exception in only that one case. It might make sense to move that to BootstrapperImpl, but that will need more investigation.
A lot of tests needed updating because XdsClientPoolProvider is no longer responsible for parsing the bootstrap, so we now need bootstraps even if XdsClientPoolProvider will ignore it.
This also fixes a bug in GoogleCloudToProdNameResolver where it would initialize the delegate even when it failed to create the bootstrap. That would certainly cause all RPCs on the channel to fail because of the missing bootstrap and it defeated the point of
succeeded == falseandrefresh()which was supposed to retry contacting the metadata server.The server tests were enhanced to give a useful error when server.start() throws an exception, as otherwise the real error is lost.
b/442819521
CC @shivaspeaks