Skip to content

grpc: change the LB policy config parsing API to accept JSON values instead of String #2294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 27, 2025

Conversation

easwars
Copy link
Contributor

@easwars easwars commented Jun 5, 2025

The existing parse_config method on the LbPolicyBuilder trait accepts configuration as a &str. Passing parsed JSON to this API is better for the following reasons:

  • the LB policy configuration is part of the ServiceConfig which is also represented as JSON. The channel would parse the service config before even attempting to send the LB policy configuration portion of the ServiceConfig to the LB policy builder. Therefore, the LB policy configuration is already available as parsed JSON.
  • Aligns better with other gRPC languages (except Go).

@easwars
Copy link
Contributor Author

easwars commented Jun 5, 2025

@dfawley @LucioFranco

/// JSON. Hides internal storage details and includes a method to deserialize
/// the JSON into a concrete policy struct.
#[derive(Debug)]
pub struct ParsedJsonLbConfig(pub serde_json::Value);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pub struct ParsedJsonLbConfig(pub serde_json::Value);
pub struct ParsedJsonLbConfig(serde_json::Value);

The idea is to encapsulate serde_json and not expose it outside our crate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently the channel (in the gracefulswitch LB policy) specifies a default service config (with pick_first as the LB policy). So, we have a few options:

  • Make this field pub(super) so that the channel has access to this field. Also, maybe the channel would want this when it implements the service config parsing from the resolver?
  • Make this field pub(crate) if other tests end wanting to set a service config.
  • Have an associated function new that takes the input JSON as a string, and returns Result<Self, String>.
    • we could use the serde_json::from_str function to convert the input string into a serde_json::Value

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

New function makes the most sense or you can even implement FromStr, exposing the internal type to modules outside of this file is generally a bad idea. (eg you want to add a field to this struct then you need to refactor all the locations that reference the internals.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the value to be a struct field instead of this being a tuple struct.

Also, added a new function.

@easwars
Copy link
Contributor Author

easwars commented Jun 23, 2025

Gentle ping on this PR: @LucioFranco @dfawley

@dfawley dfawley merged commit 6213dda into hyperium:next Jun 27, 2025
16 of 17 checks passed
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.

3 participants