It'd be really helpful if InternalConfigSelector was made a proper public, stable API instead of an @Internal one.
As far as I can tell it's the only way to pick config (timeouts, retries, other MethodConfig stuff) per-RPC based on the method/headers, from the resolver side, before the LB pick happens. It was originally added for xDS in gRFC A31 (xDS timeout support and config selector). I looked at the other extension points and none of them actually cover this — a static service config only does exact per-service/per-method matching, a ClientInterceptor runs too late and can't feed the channel's service-config machinery (it can't hand back the parsed config the channel expects), and a LoadBalancer sits below where this needs to happen. So right now if you need this you're stuck depending on an @Internal class, which can just change or break on any minor release. That's a hard thing to build on top of.
It isn't just a made-up use-case – we had previously discussed HTTP connection-sharing in #12572. The recommendation there was to share one real ManagedChannel across a bunch of services (keep them in a map, refcount them, hand back a shim ManagedChannel per service). But once you collapse many services onto a single shared channel, that channel can't carry a separate static service config per service anymore — you have to pick the right service's config per RPC, based on which service the call is going to. InternalConfigSelector is the only thing that lets you do that, so it's basically a prerequisite for actually implementing that shared-channel idea.
Stabilizing it shouldn't cost much. gRPC's own xDS support (A28/A31/A39 etc.) is built entirely on this, and the shape hasn't really changed in years, so it's already proven in production. It'd just need a real name, a documented contract (e.g. that Result.getConfig() has to be the parsed object from ServiceConfigParser, and that you have to send a valid service config alongside the selector — both of which are easy to trip over), and a commitment not to break it. Then people could build resolver-driven config/routing, and the #12572 shared-channel pattern, without pinning to internals.
Is your feature request related to a problem?
InternalConfigSelector is the only way to do per-RPC, resolver-driven config selection (timeouts/retries/MethodConfig by method/headers) before the LB pick, but it's @Internal , so building on it means depending on something that can break on any minor release.
Describe the solution you'd like
Promote InternalConfigSelector to a supported, stable public API — with a real name, a documented contract (e.g. Result.getConfig() must be the parsed object from ServiceConfigParser, and a valid service config must accompany the selector), and a commitment not to break it.
Describe alternatives you've considered
Static service config (only exact per-service/per-method matching), a ClientInterceptor (runs too late and can't feed the channel's service-config machinery), and a custom LoadBalancer (sits below where this decision has to happen) — none of them can express per-RPC config selection.
Additional context
It's the missing piece for the shared-ManagedChannel design the maintainers recommended in #12572 (per-service config on a single shared channel must be chosen per-RPC); it originated in gRFC A31 and is already the proven, stable foundation of gRPC's own xDS stack (A28/A31/A39), so stabilizing it should be low-cost.
It'd be really helpful if
InternalConfigSelectorwas made a proper public, stable API instead of an@Internalone.As far as I can tell it's the only way to pick config (timeouts, retries, other
MethodConfigstuff) per-RPC based on the method/headers, from the resolver side, before the LB pick happens. It was originally added for xDS in gRFC A31 (xDS timeout support and config selector). I looked at the other extension points and none of them actually cover this — a static service config only does exact per-service/per-method matching, a ClientInterceptor runs too late and can't feed the channel's service-config machinery (it can't hand back the parsed config the channel expects), and a LoadBalancer sits below where this needs to happen. So right now if you need this you're stuck depending on an@Internalclass, which can just change or break on any minor release. That's a hard thing to build on top of.It isn't just a made-up use-case – we had previously discussed HTTP connection-sharing in #12572. The recommendation there was to share one real
ManagedChannelacross a bunch of services (keep them in a map, refcount them, hand back a shimManagedChannelper service). But once you collapse many services onto a single shared channel, that channel can't carry a separate static service config per service anymore — you have to pick the right service's config per RPC, based on which service the call is going to.InternalConfigSelectoris the only thing that lets you do that, so it's basically a prerequisite for actually implementing that shared-channel idea.Stabilizing it shouldn't cost much. gRPC's own xDS support (A28/A31/A39 etc.) is built entirely on this, and the shape hasn't really changed in years, so it's already proven in production. It'd just need a real name, a documented contract (e.g. that Result.getConfig() has to be the parsed object from
ServiceConfigParser, and that you have to send a valid service config alongside the selector — both of which are easy to trip over), and a commitment not to break it. Then people could build resolver-driven config/routing, and the #12572 shared-channel pattern, without pinning to internals.Is your feature request related to a problem?
InternalConfigSelectoris the only way to do per-RPC, resolver-driven config selection (timeouts/retries/MethodConfigby method/headers) before the LB pick, but it's@Internal, so building on it means depending on something that can break on any minor release.Describe the solution you'd like
Promote
InternalConfigSelectorto a supported, stable public API — with a real name, a documented contract (e.g.Result.getConfig()must be the parsed object fromServiceConfigParser, and a valid service config must accompany the selector), and a commitment not to break it.Describe alternatives you've considered
Static service config (only exact per-service/per-method matching), a
ClientInterceptor(runs too late and can't feed the channel's service-config machinery), and a customLoadBalancer(sits below where this decision has to happen) — none of them can express per-RPC config selection.Additional context
It's the missing piece for the shared-
ManagedChanneldesign the maintainers recommended in #12572 (per-service config on a single shared channel must be chosen per-RPC); it originated in gRFC A31 and is already the proven, stable foundation of gRPC's own xDS stack (A28/A31/A39), so stabilizing it should be low-cost.