Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / google.golang.org / grpc / pickfirst.go
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 grpc
20
21 import (
22         "context"
23
24         "google.golang.org/grpc/balancer"
25         "google.golang.org/grpc/connectivity"
26         "google.golang.org/grpc/grpclog"
27         "google.golang.org/grpc/resolver"
28 )
29
30 // PickFirstBalancerName is the name of the pick_first balancer.
31 const PickFirstBalancerName = "pick_first"
32
33 func newPickfirstBuilder() balancer.Builder {
34         return &pickfirstBuilder{}
35 }
36
37 type pickfirstBuilder struct{}
38
39 func (*pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
40         return &pickfirstBalancer{cc: cc}
41 }
42
43 func (*pickfirstBuilder) Name() string {
44         return PickFirstBalancerName
45 }
46
47 type pickfirstBalancer struct {
48         cc balancer.ClientConn
49         sc balancer.SubConn
50 }
51
52 func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
53         if err != nil {
54                 grpclog.Infof("pickfirstBalancer: HandleResolvedAddrs called with error %v", err)
55                 return
56         }
57         if b.sc == nil {
58                 b.sc, err = b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{})
59                 if err != nil {
60                         //TODO(yuxuanli): why not change the cc state to Idle?
61                         grpclog.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err)
62                         return
63                 }
64                 b.cc.UpdateBalancerState(connectivity.Idle, &picker{sc: b.sc})
65                 b.sc.Connect()
66         } else {
67                 b.sc.UpdateAddresses(addrs)
68                 b.sc.Connect()
69         }
70 }
71
72 func (b *pickfirstBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
73         grpclog.Infof("pickfirstBalancer: HandleSubConnStateChange: %p, %v", sc, s)
74         if b.sc != sc {
75                 grpclog.Infof("pickfirstBalancer: ignored state change because sc is not recognized")
76                 return
77         }
78         if s == connectivity.Shutdown {
79                 b.sc = nil
80                 return
81         }
82
83         switch s {
84         case connectivity.Ready, connectivity.Idle:
85                 b.cc.UpdateBalancerState(s, &picker{sc: sc})
86         case connectivity.Connecting:
87                 b.cc.UpdateBalancerState(s, &picker{err: balancer.ErrNoSubConnAvailable})
88         case connectivity.TransientFailure:
89                 b.cc.UpdateBalancerState(s, &picker{err: balancer.ErrTransientFailure})
90         }
91 }
92
93 func (b *pickfirstBalancer) Close() {
94 }
95
96 type picker struct {
97         err error
98         sc  balancer.SubConn
99 }
100
101 func (p *picker) Pick(ctx context.Context, opts balancer.PickOptions) (balancer.SubConn, func(balancer.DoneInfo), error) {
102         if p.err != nil {
103                 return nil, nil, p.err
104         }
105         return p.sc, nil, nil
106 }
107
108 func init() {
109         balancer.Register(newPickfirstBuilder())
110 }