Skip to content
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

endpointsharding, lazy: Remove intermediary gracefulswitch balancers #8052

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

arjan-bal
Copy link
Contributor

@arjan-bal arjan-bal commented Jan 30, 2025

Presently both lazy and endpointsharding create gracefulswtich balancers to manage their children. The gracefulswitch balancer is unnecessary as the type of the child balancer in not expected to change in existing use cases. Having the gracefulswitch child requires the child balancer's builder to be registered in the global LB registry. The lazy LB is not a complete LB policy and should not be registered globally.

This PR makes the constructors of endpointpointsharding and lazy accept the child balancer's builder to avoid using the global registry. This PR also removes the ParseConfig functions/methods in lazy and endpointsharding as they will simply forward the LoadBalancingConfigs to their children. The children are responsible to parse the LoadBalancingConfig JSON. Since pickfirst can use a nil LoadBalancingConfig, the existing users of endpointsharding don't need to provide a LoadBalancingConfig.

RELEASE NOTES:

  • balancer/endpointsharding: The constructor accepts the child balancer's builder and a struct with optional configuration.
  • balancer/endpointsharding: Balancers created with the new DisableAutoReconnect option will not attempt to call ExitIdle automatically on their children when the children report idle.

@arjan-bal arjan-bal added the Type: Internal Cleanup Refactors, etc label Jan 30, 2025
@arjan-bal arjan-bal added this to the 1.71 Release milestone Jan 30, 2025
@arjan-bal arjan-bal requested a review from dfawley January 30, 2025 10:50
Copy link

codecov bot commented Jan 30, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.17%. Comparing base (b0e2ae9) to head (12d3752).
Report is 9 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8052      +/-   ##
==========================================
- Coverage   82.29%   82.17%   -0.12%     
==========================================
  Files         384      387       +3     
  Lines       38926    38981      +55     
==========================================
  Hits        32034    32034              
- Misses       5565     5610      +45     
- Partials     1327     1337      +10     
Files with missing lines Coverage Δ
balancer/endpointsharding/endpointsharding.go 79.09% <100.00%> (+1.96%) ⬆️
balancer/lazy/lazy.go 81.53% <100.00%> (+7.11%) ⬆️
balancer/leastrequest/leastrequest.go 88.69% <100.00%> (ø)
balancer/weightedroundrobin/balancer.go 83.38% <100.00%> (-0.10%) ⬇️

... and 48 files with indirect coverage changes

Copy link
Member

@dfawley dfawley left a comment

Choose a reason for hiding this comment

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

Mostly looks fine, but the minor API thing should be decided.

@@ -100,7 +99,7 @@ func (crr *customRoundRobin) UpdateClientConnState(state balancer.ClientConnStat
// is guaranteed to happen since the aggregator will always call
// UpdateChildState in its UpdateClientConnState.
return crr.Balancer.UpdateClientConnState(balancer.ClientConnState{
BalancerConfig: gracefulSwitchPickFirst,
BalancerConfig: nil, // pickfirst can handle nil configs.
Copy link
Member

Choose a reason for hiding this comment

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

Delete the field entirely to remove complications from example?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed throughout.

@@ -236,7 +233,7 @@ func (b *wrrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error
// This causes child to update picker inline and will thus cause inline
// picker update.
return b.child.UpdateClientConnState(balancer.ClientConnState{
BalancerConfig: endpointShardingLBConfig,
BalancerConfig: nil, // pickfirst can handle nil configs.
Copy link
Member

Choose a reason for hiding this comment

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

And then I'd delete it from all our code to avoid clutter. Most LB policies should handle not having configs, except some special xds things.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

// NewBalancer returns a load balancing policy that manages homogeneous child
// policies each owning a single endpoint. The endpointsharding balancer
// forwards the LoadBalancingConfig in ClientConn state updates to its children.
func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions, childBuilder balancer.Builder, esOpts Options) balancer.Balancer {
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering about the signature here.

There's a lot of options:

  1. Keep this & make anyone wanting to use es+lazy wrap lazy in a Builder implementation.
  2. Keep this & implement a Builder in lazy, still.
  3. Create type ChildBuilder interface { Build(..) .. } without Name() and make lazy implement that.
  4. Accept a function matching the signature of Build here.

None of these are great. I think I might like (4) the best for usability? But I dislike it for understandability. I suppose that could be helped with:

type ChildBuilder = func(...) ... // matching Build

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use a type alias. Didn't export the ChildBuilder type since it's only an alias.


func (builder) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Balancer {
// NewBalancer is the constructor for the lazy balancer.
func NewBalancer(cc balancer.ClientConn, bOpts balancer.BuildOptions, childBuilder balancer.Builder) balancer.Balancer {
Copy link
Member

Choose a reason for hiding this comment

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

The same concerns as above apply here, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed, using an alias to the type of the balancer.Build method now.

@dfawley dfawley assigned arjan-bal and unassigned dfawley Jan 30, 2025
@arjan-bal arjan-bal assigned dfawley and unassigned arjan-bal Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants