Skip to content

grpc: add service config types and parsing - #2731

Open
nathanielford wants to merge 25 commits into
grpc:masterfrom
nathanielford:implement/ServiceConfig
Open

grpc: add service config types and parsing#2731
nathanielford wants to merge 25 commits into
grpc:masterfrom
nathanielford:implement/ServiceConfig

Conversation

@nathanielford

@nathanielford nathanielford commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Motivation

ServiceConfig requires an internal representation that we can de/serialize.

Solution

This CL implements the ServiceConfig struct and necessary plumbing for de/serialization. In a follow-on CL(s) we will be adding the plumbing to fully utilize the ServiceConfig, including adding the option to the Channel builde, passing it to the load balancer tree for utilization, and interactions with the Name Resolver.

Notes

  • Serde-specific data transfer objects were created so that we weren't exporting foreign types, and giving us options for de/serialization without breaking users going forward.
  • Initially this PR included deserializing stringified u32 types, in concordance with C++ and Java. We may re-implement this going forward, but for now we are forcing the json to have valid raw integers. The concern here is making sure bugs don't arise because macro annotations get missed on edits. We may decide this is stable enough that we don't care, or we may have an internal type (i.e. GrpcU32) like we do with GrpcDuration.

@nathanielford
nathanielford force-pushed the implement/ServiceConfig branch from 29c707f to 52589c3 Compare July 13, 2026 21:32
@nathanielford
nathanielford requested a review from dfawley July 13, 2026 21:43
@nathanielford
nathanielford marked this pull request as ready for review July 13, 2026 21:43
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated
Comment thread grpc/src/client/service_config/mod.rs Outdated
Comment thread grpc/src/client/channel.rs Outdated
Comment thread grpc/src/client/channel.rs Outdated
Comment thread grpc/src/inmemory/mod.rs Outdated
Comment thread grpc/src/client/service_config/mod.rs Outdated
Comment thread grpc/src/client/service_config/mod.rs Outdated
Comment thread grpc/src/client/service_config/serde.rs Outdated
Comment thread grpc/src/client/service_config/json.rs Outdated

@dfawley dfawley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. The Duration stuff LGTM; glad we can do this without needing to annotate every instance of the field individually.

Comment thread grpc/src/client/service_config/serde.rs Outdated
Comment thread grpc/src/client/service_config/serde.rs
Comment thread grpc/src/client/service_config/serde.rs Outdated
@nathanielford
nathanielford force-pushed the implement/ServiceConfig branch from f668c82 to d24c2ef Compare July 23, 2026 23:23
@dfawley dfawley assigned nathanielford and unassigned dfawley Jul 27, 2026
Comment thread grpc/src/client/service_config/mod.rs
Comment thread grpc/src/client/service_config/serde.rs Outdated
Comment thread grpc/src/client/service_config/serde.rs Outdated
Comment thread grpc/src/client/service_config/serde.rs
Comment thread grpc/src/client/service_config/mod.rs Outdated
@dfawley dfawley changed the title Implement/service config grpc: add service config types and parsing Jul 30, 2026
Comment thread grpc/src/client/service_config/mod.rs Outdated
Comment on lines +64 to +68
.map(|c| {
let mut map = serde_json::Map::new();
map.insert(c.name.clone(), c.config.clone());
serde_json::Value::Object(map)
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we want this part to do a bit more -- and during parsing, not afterwards. Here's what we do in Go per config entry:

https://github.com/grpc/grpc-go/blob/4c226daff88f54441d70f710815e07b81fb162b2/internal/serviceconfig/serviceconfig.go#L82-L120

  • Lookup the balancer in the registry; skip entry if doesn't exist
  • Call it to parse the config; error all service config parsing if it fails
  • Collapse to a single selected policy and its parsed config, not a vec.

It's nice to do this here instead of in the channel, because we have LB policies that have similar "child" fields that will want to do this exact same logic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a TODO around this. After looking at it, I'd rather do the 'mechanical' and plumbing stuff in the followup or in a smaller PR and keep this more bare bones. LMK if you think that's ok or if we keep good context by putting it here. It seems straightforward enough but would add additional files to the surface of this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind if you want to put the implementation in another PR, but then some of these abstractions I think are just wrong in light of the above, and should be deleted if they aren't updated.

  1. ServiceConfig shouldn't have a pub fn lb_config(). ServiceConfig should be completely opaque externally (only parsed and passed around).

  2. The LoadBalancingConfigSerde field should ideally (I think) parse a JSON array, but collapse it down to a single value: the first supported policy - it can also be empty if either the field is absent or if it contains no entries that are in the registry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants