1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- /*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- // Package roundrobin defines a roundrobin balancer. Roundrobin balancer is
- // installed as one of the default balancers in gRPC, users don't need to
- // explicitly install this balancer.
- package roundrobin
- import (
- "context"
- "sync"
- "google.golang.org/grpc/balancer"
- "google.golang.org/grpc/balancer/base"
- "google.golang.org/grpc/grpclog"
- "google.golang.org/grpc/internal/grpcrand"
- "google.golang.org/grpc/resolver"
- )
- // Name is the name of round_robin balancer.
- const Name = "round_robin"
- // newBuilder creates a new roundrobin balancer builder.
- func newBuilder() balancer.Builder {
- return base.NewBalancerBuilderWithConfig(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true})
- }
- func init() {
- balancer.Register(newBuilder())
- }
- type rrPickerBuilder struct{}
- func (*rrPickerBuilder) Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker {
- grpclog.Infof("roundrobinPicker: newPicker called with readySCs: %v", readySCs)
- if len(readySCs) == 0 {
- return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
- }
- var scs []balancer.SubConn
- for _, sc := range readySCs {
- scs = append(scs, sc)
- }
- return &rrPicker{
- subConns: scs,
- // Start at a random index, as the same RR balancer rebuilds a new
- // picker when SubConn states change, and we don't want to apply excess
- // load to the first server in the list.
- next: grpcrand.Intn(len(scs)),
- }
- }
- type rrPicker struct {
- // subConns is the snapshot of the roundrobin balancer when this picker was
- // created. The slice is immutable. Each Get() will do a round robin
- // selection from it and return the selected SubConn.
- subConns []balancer.SubConn
- mu sync.Mutex
- next int
- }
- func (p *rrPicker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
- p.mu.Lock()
- sc := p.subConns[p.next]
- p.next = (p.next + 1) % len(p.subConns)
- p.mu.Unlock()
- return sc, nil, nil
- }
|