cubefs
83 строки · 2.4 Кб
1/*
2*
3* Copyright 2017 gRPC authors.
4*
5* Licensed under the Apache License, Version 2.0 (the "License");
6* you may not use this file except in compliance with the License.
7* You may obtain a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*
17*/
18
19// Package roundrobin defines a roundrobin balancer. Roundrobin balancer is
20// installed as one of the default balancers in gRPC, users don't need to
21// explicitly install this balancer.
22package roundrobin
23
24import (
25"sync"
26
27"google.golang.org/grpc/balancer"
28"google.golang.org/grpc/balancer/base"
29"google.golang.org/grpc/grpclog"
30"google.golang.org/grpc/internal/grpcrand"
31)
32
33// Name is the name of round_robin balancer.
34const Name = "round_robin"
35
36var logger = grpclog.Component("roundrobin")
37
38// newBuilder creates a new roundrobin balancer builder.
39func newBuilder() balancer.Builder {
40return base.NewBalancerBuilder(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true})
41}
42
43func init() {
44balancer.Register(newBuilder())
45}
46
47type rrPickerBuilder struct{}
48
49func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
50logger.Infof("roundrobinPicker: newPicker called with info: %v", info)
51if len(info.ReadySCs) == 0 {
52return base.NewErrPicker(balancer.ErrNoSubConnAvailable)
53}
54var scs []balancer.SubConn
55for sc := range info.ReadySCs {
56scs = append(scs, sc)
57}
58return &rrPicker{
59subConns: scs,
60// Start at a random index, as the same RR balancer rebuilds a new
61// picker when SubConn states change, and we don't want to apply excess
62// load to the first server in the list.
63next: grpcrand.Intn(len(scs)),
64}
65}
66
67type rrPicker struct {
68// subConns is the snapshot of the roundrobin balancer when this picker was
69// created. The slice is immutable. Each Get() will do a round robin
70// selection from it and return the selected SubConn.
71subConns []balancer.SubConn
72
73mu sync.Mutex
74next int
75}
76
77func (p *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
78p.mu.Lock()
79sc := p.subConns[p.next]
80p.next = (p.next + 1) % len(p.subConns)
81p.mu.Unlock()
82return balancer.PickResult{SubConn: sc}, nil
83}
84