26
26
package endpointsharding
27
27
28
28
import (
29
- "encoding/json"
30
29
"errors"
31
- "fmt"
32
30
rand "math/rand/v2"
33
31
"sync"
34
32
"sync/atomic"
35
33
36
34
"google.golang.org/grpc/balancer"
37
35
"google.golang.org/grpc/balancer/base"
38
- "google.golang.org/grpc/balancer/pickfirst/pickfirstleaf"
39
36
"google.golang.org/grpc/connectivity"
40
- "google.golang.org/grpc/grpclog"
41
- "google.golang.org/grpc/internal/balancer/gracefulswitch"
42
37
"google.golang.org/grpc/resolver"
43
- "google.golang.org/grpc/serviceconfig"
44
38
)
45
39
46
- var (
47
- // PickFirstConfig is a pick first config without shuffling enabled.
48
- PickFirstConfig serviceconfig.LoadBalancingConfig
49
- logger = grpclog .Component ("endpoint-sharding" )
50
- )
51
-
52
- func init () {
53
- var err error
54
- PickFirstConfig , err = ParseConfig (json .RawMessage (fmt .Sprintf ("[{%q: {}}]" , pickfirstleaf .Name )))
55
- if err != nil {
56
- logger .Fatal (err )
57
- }
58
- }
59
-
60
40
// ChildState is the balancer state of a child along with the endpoint which
61
41
// identifies the child balancer.
62
42
type ChildState struct {
@@ -68,36 +48,26 @@ type ChildState struct {
68
48
Balancer balancer.ExitIdler
69
49
}
70
50
71
- // NewBalancer returns a load balancing policy that manages homogeneous child
72
- // policies each owning a single endpoint. The balancer will automatically call
73
- // ExitIdle on its children if they report IDLE connectivity state.
74
- func NewBalancer (cc balancer.ClientConn , opts balancer.BuildOptions ) balancer.Balancer {
75
- return newBlanacer (cc , opts , BuildOptions {})
76
- }
77
-
78
- // BuildOptions are the options to configure the behaviour of the
51
+ // Options are the options to configure the behaviour of the
79
52
// endpointsharding balancer.
80
- type BuildOptions struct {
53
+ type Options struct {
54
+ // DisableAutoReconnect allows the balancer to keep child balancer in the
55
+ // IDLE state until they are explicitly triggered to exit using the
56
+ // ChildState obtained from the endpointsharding picker. When set to false,
57
+ // the endpointsharding balancer will automatically call ExitIdle on child
58
+ // connections that report IDLE.
81
59
DisableAutoReconnect bool
82
- ChildBuilder balancer.Builder
83
60
}
84
61
85
- // NewBalancerWithOpts returns a load balancing policy that manages
86
- // homogeneous child policies each owning a single endpoint. The balancer will
87
- // allow children to remain in IDLE state until triggered to exit idle state
88
- // using the ChildState obtained using the endpointsharding picker.
89
- func NewBalancerWithOpts (cc balancer.ClientConn , opts balancer.BuildOptions , epOpts BuildOptions ) balancer.Balancer {
90
- return newBlanacer (cc , opts , epOpts )
91
- }
92
-
93
- func newBlanacer (cc balancer.ClientConn , opts balancer.BuildOptions , epOpts BuildOptions ) balancer.Balancer {
94
- if epOpts .ChildBuilder == nil {
95
- epOpts .ChildBuilder = & gracefulSwitchBuilder {}
96
- }
62
+ // NewBalancer returns a load balancing policy that manages homogeneous child
63
+ // policies each owning a single endpoint. The endpointsharding balancer
64
+ // forwards the LoadBalancingConfig in ClientConn state updates to its children.
65
+ func NewBalancer (cc balancer.ClientConn , opts balancer.BuildOptions , childBuilder balancer.Builder , esOpts Options ) balancer.Balancer {
97
66
es := & endpointSharding {
98
- cc : cc ,
99
- bOpts : opts ,
100
- epOpts : epOpts ,
67
+ cc : cc ,
68
+ bOpts : opts ,
69
+ esOpts : esOpts ,
70
+ childBuilder : childBuilder ,
101
71
}
102
72
es .children .Store (resolver .NewEndpointMap ())
103
73
return es
@@ -107,9 +77,10 @@ func newBlanacer(cc balancer.ClientConn, opts balancer.BuildOptions, epOpts Buil
107
77
// balancer with child config for every unique Endpoint received. It updates the
108
78
// child states on any update from parent or child.
109
79
type endpointSharding struct {
110
- cc balancer.ClientConn
111
- bOpts balancer.BuildOptions
112
- epOpts BuildOptions
80
+ cc balancer.ClientConn
81
+ bOpts balancer.BuildOptions
82
+ esOpts Options
83
+ childBuilder balancer.Builder
113
84
114
85
// childMu synchronizes calls to any single child. It must be held for all
115
86
// calls into a child. To avoid deadlocks, do not acquire childMu while
@@ -170,7 +141,7 @@ func (es *endpointSharding) UpdateClientConnState(state balancer.ClientConnState
170
141
es : es ,
171
142
}
172
143
childBalancer .childState .Balancer = childBalancer
173
- childBalancer .child = es .epOpts . ChildBuilder .Build (childBalancer , es .bOpts )
144
+ childBalancer .child = es .childBuilder .Build (childBalancer , es .bOpts )
174
145
}
175
146
newChildren .Set (endpoint , childBalancer )
176
147
if err := childBalancer .updateClientConnStateLocked (balancer.ClientConnState {
@@ -344,7 +315,7 @@ func (bw *balancerWrapper) UpdateState(state balancer.State) {
344
315
bw .es .mu .Lock ()
345
316
bw .childState .State = state
346
317
bw .es .mu .Unlock ()
347
- if state .ConnectivityState == connectivity .Idle && ! bw .es .epOpts .DisableAutoReconnect {
318
+ if state .ConnectivityState == connectivity .Idle && ! bw .es .esOpts .DisableAutoReconnect {
348
319
bw .ExitIdle ()
349
320
}
350
321
bw .es .updateState ()
@@ -380,23 +351,3 @@ func (bw *balancerWrapper) closeLocked() {
380
351
bw .child .Close ()
381
352
bw .isClosed = true
382
353
}
383
-
384
- // ParseConfig parses a child config list and returns an LB config to use with
385
- // the endpointsharding balancer.
386
- //
387
- // cfg is expected to be a JSON array of LB policy names + configs as the
388
- // format of the loadBalancingConfig field in ServiceConfig.
389
- func ParseConfig (cfg json.RawMessage ) (serviceconfig.LoadBalancingConfig , error ) {
390
- return gracefulswitch .ParseConfig (cfg )
391
- }
392
-
393
- type gracefulSwitchBuilder struct {
394
- }
395
-
396
- func (b * gracefulSwitchBuilder ) Build (cc balancer.ClientConn , opts balancer.BuildOptions ) balancer.Balancer {
397
- return gracefulswitch .NewBalancer (cc , opts )
398
- }
399
-
400
- func (b * gracefulSwitchBuilder ) Name () string {
401
- return "gracefulswitch"
402
- }
0 commit comments