|
|
@@ -28,47 +28,31 @@ import (
|
|
|
_ "google.golang.org/grpc/resolver/passthrough" // register passthrough resolver
|
|
|
)
|
|
|
|
|
|
-// Balancer defines client balancer interface.
|
|
|
-type Balancer interface {
|
|
|
- // Builder is called at the beginning to initialize sub-connection states and picker.
|
|
|
- balancer.Builder
|
|
|
-
|
|
|
- // Balancer is called on specified client connection. Client initiates gRPC
|
|
|
- // connection with "grpc.Dial(addr, grpc.WithBalancerName)", and then those resolved
|
|
|
- // addresses are passed to "grpc/balancer.Balancer.HandleResolvedAddrs".
|
|
|
- // For each resolved address, balancer calls "balancer.ClientConn.NewSubConn".
|
|
|
- // "grpc/balancer.Balancer.HandleSubConnStateChange" is called when connectivity state
|
|
|
- // changes, thus requires failover logic in this method.
|
|
|
- balancer.Balancer
|
|
|
+// RegisterBuilder creates and registers a builder. Since this function calls balancer.Register, it
|
|
|
+// must be invoked at initialization time.
|
|
|
+func RegisterBuilder(cfg Config) {
|
|
|
+ bb := &builder{cfg}
|
|
|
+ balancer.Register(bb)
|
|
|
|
|
|
- // Picker calls "Pick" for every client request.
|
|
|
- picker.Picker
|
|
|
+ bb.cfg.Logger.Info(
|
|
|
+ "registered balancer",
|
|
|
+ zap.String("policy", bb.cfg.Policy.String()),
|
|
|
+ zap.String("name", bb.cfg.Name),
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
-type baseBalancer struct {
|
|
|
- policy picker.Policy
|
|
|
- name string
|
|
|
- lg *zap.Logger
|
|
|
-
|
|
|
- mu sync.RWMutex
|
|
|
-
|
|
|
- addrToSc map[resolver.Address]balancer.SubConn
|
|
|
- scToAddr map[balancer.SubConn]resolver.Address
|
|
|
- scToSt map[balancer.SubConn]connectivity.State
|
|
|
-
|
|
|
- currentConn balancer.ClientConn
|
|
|
- currentState connectivity.State
|
|
|
- csEvltr *connectivityStateEvaluator
|
|
|
-
|
|
|
- picker.Picker
|
|
|
+type builder struct {
|
|
|
+ cfg Config
|
|
|
}
|
|
|
|
|
|
-// New returns a new balancer from specified picker policy.
|
|
|
-func New(cfg Config) Balancer {
|
|
|
+// Build is called initially when creating "ccBalancerWrapper".
|
|
|
+// "grpc.Dial" is called to this client connection.
|
|
|
+// Then, resolved addreses will be handled via "HandleResolvedAddrs".
|
|
|
+func (b *builder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
|
|
|
bb := &baseBalancer{
|
|
|
- policy: cfg.Policy,
|
|
|
- name: cfg.Policy.String(),
|
|
|
- lg: cfg.Logger,
|
|
|
+ policy: b.cfg.Policy,
|
|
|
+ name: b.cfg.Policy.String(),
|
|
|
+ lg: b.cfg.Logger,
|
|
|
|
|
|
addrToSc: make(map[resolver.Address]balancer.SubConn),
|
|
|
scToAddr: make(map[balancer.SubConn]resolver.Address),
|
|
|
@@ -80,30 +64,13 @@ func New(cfg Config) Balancer {
|
|
|
// initialize picker always returns "ErrNoSubConnAvailable"
|
|
|
Picker: picker.NewErr(balancer.ErrNoSubConnAvailable),
|
|
|
}
|
|
|
- if cfg.Name != "" {
|
|
|
- bb.name = cfg.Name
|
|
|
+ if b.cfg.Name != "" {
|
|
|
+ bb.name = b.cfg.Name
|
|
|
}
|
|
|
if bb.lg == nil {
|
|
|
bb.lg = zap.NewNop()
|
|
|
}
|
|
|
|
|
|
- balancer.Register(bb)
|
|
|
- bb.lg.Info(
|
|
|
- "registered balancer",
|
|
|
- zap.String("policy", bb.policy.String()),
|
|
|
- zap.String("name", bb.name),
|
|
|
- )
|
|
|
- return bb
|
|
|
-}
|
|
|
-
|
|
|
-// Name implements "grpc/balancer.Builder" interface.
|
|
|
-func (bb *baseBalancer) Name() string { return bb.name }
|
|
|
-
|
|
|
-// Build implements "grpc/balancer.Builder" interface.
|
|
|
-// Build is called initially when creating "ccBalancerWrapper".
|
|
|
-// "grpc.Dial" is called to this client connection.
|
|
|
-// Then, resolved addreses will be handled via "HandleResolvedAddrs".
|
|
|
-func (bb *baseBalancer) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer {
|
|
|
// TODO: support multiple connections
|
|
|
bb.mu.Lock()
|
|
|
bb.currentConn = cc
|
|
|
@@ -117,6 +84,41 @@ func (bb *baseBalancer) Build(cc balancer.ClientConn, opt balancer.BuildOptions)
|
|
|
return bb
|
|
|
}
|
|
|
|
|
|
+// Name implements "grpc/balancer.Builder" interface.
|
|
|
+func (b *builder) Name() string { return b.cfg.Name }
|
|
|
+
|
|
|
+// Balancer defines client balancer interface.
|
|
|
+type Balancer interface {
|
|
|
+ // Balancer is called on specified client connection. Client initiates gRPC
|
|
|
+ // connection with "grpc.Dial(addr, grpc.WithBalancerName)", and then those resolved
|
|
|
+ // addresses are passed to "grpc/balancer.Balancer.HandleResolvedAddrs".
|
|
|
+ // For each resolved address, balancer calls "balancer.ClientConn.NewSubConn".
|
|
|
+ // "grpc/balancer.Balancer.HandleSubConnStateChange" is called when connectivity state
|
|
|
+ // changes, thus requires failover logic in this method.
|
|
|
+ balancer.Balancer
|
|
|
+
|
|
|
+ // Picker calls "Pick" for every client request.
|
|
|
+ picker.Picker
|
|
|
+}
|
|
|
+
|
|
|
+type baseBalancer struct {
|
|
|
+ policy picker.Policy
|
|
|
+ name string
|
|
|
+ lg *zap.Logger
|
|
|
+
|
|
|
+ mu sync.RWMutex
|
|
|
+
|
|
|
+ addrToSc map[resolver.Address]balancer.SubConn
|
|
|
+ scToAddr map[balancer.SubConn]resolver.Address
|
|
|
+ scToSt map[balancer.SubConn]connectivity.State
|
|
|
+
|
|
|
+ currentConn balancer.ClientConn
|
|
|
+ currentState connectivity.State
|
|
|
+ csEvltr *connectivityStateEvaluator
|
|
|
+
|
|
|
+ picker.Picker
|
|
|
+}
|
|
|
+
|
|
|
// HandleResolvedAddrs implements "grpc/balancer.Balancer" interface.
|
|
|
// gRPC sends initial or updated resolved addresses from "Build".
|
|
|
func (bb *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
|