-
Notifications
You must be signed in to change notification settings - Fork 4.7k
A75: Implement the new LB policy topology for the non-aggregate cluster #9234
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
base: master
Are you sure you want to change the base?
Changes from all commits
533dafb
5516779
9b3c703
fbed93a
c1ab2d9
785be23
51e986e
e7c0475
d6a83ca
31d6b4c
53b4209
9f43e37
f2fc6b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,6 @@ import ( | |
| "google.golang.org/grpc/balancer" | ||
| "google.golang.org/grpc/balancer/base" | ||
| "google.golang.org/grpc/connectivity" | ||
| "google.golang.org/grpc/internal/balancer/nop" | ||
| "google.golang.org/grpc/internal/grpclog" | ||
| "google.golang.org/grpc/internal/pretty" | ||
| internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" | ||
|
|
@@ -41,16 +40,20 @@ import ( | |
| const cdsName = "cds_experimental" | ||
|
|
||
| var ( | ||
| // newChildBalancer is a helper function to build a new priority balancer | ||
| // and will be overridden in unittests. | ||
| newChildBalancer = func(cc balancer.ClientConn, opts balancer.BuildOptions) (balancer.Balancer, error) { | ||
| builder := balancer.Get(priority.Name) | ||
| // newChildBalancer is a helper function to build a new child balancer | ||
| // and its config parser, and will be overridden in unittests. | ||
| newChildBalancer = func(name string, cc balancer.ClientConn, opts balancer.BuildOptions) (balancer.Balancer, balancer.ConfigParser, error) { | ||
| builder := balancer.Get(name) | ||
| if builder == nil { | ||
| return nil, fmt.Errorf("xds: no balancer builder with name %v", priority.Name) | ||
| return nil, nil, fmt.Errorf("xds: no balancer builder with name %v", name) | ||
| } | ||
| // We directly pass the parent clientConn to the underlying priority | ||
| parser, ok := builder.(balancer.ConfigParser) | ||
| if !ok { | ||
| return nil, nil, fmt.Errorf("xds: balancer builder for %v does not implement ConfigParser", name) | ||
| } | ||
| // We directly pass the parent clientConn to the underlying child | ||
| // balancer because the cdsBalancer does not deal with subConns. | ||
| return builder.Build(cc, opts), nil | ||
| return builder.Build(cc, opts), parser, nil | ||
| } | ||
| ) | ||
|
|
||
|
|
@@ -65,26 +68,11 @@ type bb struct{} | |
|
|
||
| // Build creates a new CDS balancer with the ClientConn. | ||
| func (bb) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer { | ||
| builder := balancer.Get(priority.Name) | ||
| if builder == nil { | ||
| // Shouldn't happen, registered through imported Priority builder. Still, | ||
| // defensive programming. | ||
| logger.Errorf("%q LB policy is needed but not registered", priority.Name) | ||
| return nop.NewBalancer(cc, fmt.Errorf("%q LB policy is needed but not registered", priority.Name)) | ||
| } | ||
| parser, ok := builder.(balancer.ConfigParser) | ||
| if !ok { | ||
| // Shouldn't happen, imported Priority builder has this method. | ||
| logger.Errorf("%q LB policy does not implement a config parser", priority.Name) | ||
| return nop.NewBalancer(cc, fmt.Errorf("%q LB policy does not implement a config parser", priority.Name)) | ||
| } | ||
|
|
||
| b := &cdsBalancer{ | ||
| bOpts: opts, | ||
| childConfigParser: parser, | ||
| clusterConfigs: make(map[string]*xdsresource.ClusterResult), | ||
| priorityConfigs: make(map[string]*priorityConfig), | ||
| cc: cc, | ||
| bOpts: opts, | ||
| clusterConfigs: make(map[string]*xdsresource.ClusterResult), | ||
| priorityConfigs: make(map[string]*priorityConfig), | ||
| cc: cc, | ||
| } | ||
| b.logger = prefixLogger(b) | ||
| b.logger.Infof("Created") | ||
|
|
@@ -134,6 +122,7 @@ type cdsBalancer struct { | |
| // protect access to these fields. | ||
| xdsClient xdsclient.XDSClient | ||
| childLB balancer.Balancer // Child policy, built upon resolution of the cluster graph. | ||
| childLBName string // Name of the child policy. | ||
| clusterConfigs map[string]*xdsresource.ClusterResult // Cluster name to the last received result for that cluster. | ||
| priorityConfigs map[string]*priorityConfig // Hostname to priority config for that leaf cluster. | ||
| lbCfg *lbConfig // Current load balancing configuration. | ||
|
|
@@ -267,18 +256,45 @@ func (b *cdsBalancer) handleClusterUpdate() error { | |
| // A child policy is created if one doesn't already exist. The newly built | ||
| // configuration is then pushed to the child policy. | ||
| func (b *cdsBalancer) updateChildConfig() error { | ||
| clusterName := b.lbCfg.ClusterName | ||
| clusterConfig := b.clusterConfigs[clusterName].Config | ||
| isAggregate := clusterConfig.Cluster.ClusterType == xdsresource.ClusterTypeAggregate | ||
|
|
||
| var topLBName string | ||
| if isAggregate { | ||
| topLBName = priority.Name | ||
| } else { | ||
| topLBName = outlierdetection.Name | ||
| } | ||
|
|
||
| if b.childLB != nil && b.childLBName != topLBName { | ||
| b.childLB.Close() | ||
| b.childLB = nil | ||
| } | ||
|
|
||
| if b.childLB == nil { | ||
| childLB, err := newChildBalancer(b.cc, b.bOpts) | ||
| childLB, parser, err := newChildBalancer(topLBName, b.cc, b.bOpts) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to create child policy of type %s: %v", priority.Name, err) | ||
| return fmt.Errorf("failed to create child policy of type %s: %v", topLBName, err) | ||
| } | ||
| b.childLB = childLB | ||
| b.childLBName = topLBName | ||
| b.childConfigParser = parser | ||
| } | ||
|
|
||
| childCfgBytes, endpoints, err := buildPriorityConfigJSON(b.priorities, &b.xdsLBPolicy) | ||
| var childCfgBytes []byte | ||
| var endpoints []resolver.Endpoint | ||
| var err error | ||
|
|
||
| if isAggregate { | ||
| childCfgBytes, endpoints, err = buildAggregateClusterConfigJSON(b.priorities, &b.xdsLBPolicy) | ||
| } else { | ||
| childCfgBytes, endpoints, err = buildLeafClusterConfigJSON(b.priorities, &b.xdsLBPolicy) | ||
| } | ||
|
mswierq marked this conversation as resolved.
Comment on lines
+289
to
+293
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the variable
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. after reverting |
||
| if err != nil { | ||
| return fmt.Errorf("failed to build child policy config: %v", err) | ||
| } | ||
|
|
||
| childCfg, err := b.childConfigParser.ParseConfig(childCfgBytes) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to parse child policy config. This should never happen because the config was generated: %v", err) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.