roundrobin.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 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	"fmt"
26
27	"google.golang.org/grpc/balancer"
28	"google.golang.org/grpc/balancer/endpointsharding"
29	"google.golang.org/grpc/balancer/pickfirst/pickfirstleaf"
30	"google.golang.org/grpc/grpclog"
31	internalgrpclog "google.golang.org/grpc/internal/grpclog"
32)
33
34// Name is the name of round_robin balancer.
35const Name = "round_robin"
36
37var logger = grpclog.Component("roundrobin")
38
39func init() {
40	balancer.Register(builder{})
41}
42
43type builder struct{}
44
45func (bb builder) Name() string {
46	return Name
47}
48
49func (bb builder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
50	childBuilder := balancer.Get(pickfirstleaf.Name).Build
51	bal := &rrBalancer{
52		cc:       cc,
53		Balancer: endpointsharding.NewBalancer(cc, opts, childBuilder, endpointsharding.Options{}),
54	}
55	bal.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[%p] ", bal))
56	bal.logger.Infof("Created")
57	return bal
58}
59
60type rrBalancer struct {
61	balancer.Balancer
62	cc     balancer.ClientConn
63	logger *internalgrpclog.PrefixLogger
64}
65
66func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
67	return b.Balancer.UpdateClientConnState(balancer.ClientConnState{
68		// Enable the health listener in pickfirst children for client side health
69		// checks and outlier detection, if configured.
70		ResolverState: pickfirstleaf.EnableHealthListener(ccs.ResolverState),
71	})
72}
73
74func (b *rrBalancer) ExitIdle() {
75	// Should always be ok, as child is endpoint sharding.
76	if ei, ok := b.Balancer.(balancer.ExitIdler); ok {
77		ei.ExitIdle()
78	}
79}