@@ -30,6 +30,7 @@ import (
3030 "github.com/golang/protobuf/proto"
3131 "google.golang.org/grpc"
3232 "google.golang.org/grpc/balancer"
33+ "google.golang.org/grpc/balancer/leastrequest"
3334 "google.golang.org/grpc/balancer/roundrobin"
3435 "google.golang.org/grpc/balancer/weightedroundrobin"
3536 "google.golang.org/grpc/internal/envconfig"
@@ -41,6 +42,7 @@ import (
4142 v1xdsudpatypepb "github.com/cncf/xds/go/udpa/type/v1"
4243 v3xdsxdstypepb "github.com/cncf/xds/go/xds/type/v3"
4344 v3clientsideweightedroundrobinpb "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3"
45+ v3leastrequestpb "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/least_request/v3"
4446 v3pickfirstpb "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/pick_first/v3"
4547 v3ringhashpb "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/ring_hash/v3"
4648 v3wrrlocalitypb "github.com/envoyproxy/go-control-plane/envoy/extensions/load_balancing_policies/wrr_locality/v3"
@@ -53,13 +55,15 @@ func init() {
5355 xdslbregistry .Register ("type.googleapis.com/envoy.extensions.load_balancing_policies.pick_first.v3.PickFirst" , convertPickFirstProtoToServiceConfig )
5456 xdslbregistry .Register ("type.googleapis.com/envoy.extensions.load_balancing_policies.round_robin.v3.RoundRobin" , convertRoundRobinProtoToServiceConfig )
5557 xdslbregistry .Register ("type.googleapis.com/envoy.extensions.load_balancing_policies.wrr_locality.v3.WrrLocality" , convertWRRLocalityProtoToServiceConfig )
58+ xdslbregistry .Register ("type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest" , convertLeastRequestProtoToServiceConfig )
5659 xdslbregistry .Register ("type.googleapis.com/udpa.type.v1.TypedStruct" , convertV1TypedStructToServiceConfig )
5760 xdslbregistry .Register ("type.googleapis.com/xds.type.v3.TypedStruct" , convertV3TypedStructToServiceConfig )
5861}
5962
6063const (
61- defaultRingHashMinSize = 1024
62- defaultRingHashMaxSize = 8 * 1024 * 1024 // 8M
64+ defaultRingHashMinSize = 1024
65+ defaultRingHashMaxSize = 8 * 1024 * 1024 // 8M
66+ defaultLeastRequestChoiceCount = 2
6367)
6468
6569func convertRingHashProtoToServiceConfig (rawProto []byte , _ int ) (json.RawMessage , error ) {
@@ -177,6 +181,29 @@ func convertWeightedRoundRobinProtoToServiceConfig(rawProto []byte, _ int) (json
177181 return makeBalancerConfigJSON (weightedroundrobin .Name , lbCfgJSON ), nil
178182}
179183
184+ func convertLeastRequestProtoToServiceConfig (rawProto []byte , _ int ) (json.RawMessage , error ) {
185+ if ! envconfig .LeastRequestLB {
186+ return nil , nil
187+ }
188+ lrProto := & v3leastrequestpb.LeastRequest {}
189+ if err := proto .Unmarshal (rawProto , lrProto ); err != nil {
190+ return nil , fmt .Errorf ("failed to unmarshal resource: %v" , err )
191+ }
192+ // "The configuration for the Least Request LB policy is the
193+ // least_request_lb_config field. The field is optional; if not present,
194+ // defaults will be assumed for all of its values." - A48
195+ choiceCount := uint32 (defaultLeastRequestChoiceCount )
196+ if cc := lrProto .GetChoiceCount (); cc != nil {
197+ choiceCount = cc .GetValue ()
198+ }
199+ lrCfg := & leastrequest.LBConfig {ChoiceCount : choiceCount }
200+ js , err := json .Marshal (lrCfg )
201+ if err != nil {
202+ return nil , fmt .Errorf ("error marshaling JSON for type %T: %v" , lrCfg , err )
203+ }
204+ return makeBalancerConfigJSON (leastrequest .Name , js ), nil
205+ }
206+
180207func convertV1TypedStructToServiceConfig (rawProto []byte , _ int ) (json.RawMessage , error ) {
181208 tsProto := & v1xdsudpatypepb.TypedStruct {}
182209 if err := proto .Unmarshal (rawProto , tsProto ); err != nil {
0 commit comments