@@ -18,6 +18,7 @@ import (
1818// routine – that is, not a runtime metric) and interprets it as inversion of
1919// weight.
2020type roundRobin struct {
21+ mu sync.RWMutex
2122 min float32
2223 max float32
2324 belt []int
@@ -32,28 +33,29 @@ func (r *roundRobin) Create() balancer.Balancer {
3233
3334func RoundRobin () balancer.Balancer {
3435 return & roundRobin {
35- r : rand .New (),
36+ r : rand .New (rand . WithLock () ),
3637 }
3738}
3839
3940func RandomChoice () balancer.Balancer {
4041 return & randomChoice {
4142 roundRobin : roundRobin {
42- r : rand .New (),
43+ r : rand .New (rand . WithLock () ),
4344 },
4445 }
4546}
4647
4748type randomChoice struct {
4849 roundRobin
49- m sync.Mutex
5050}
5151
5252func (r * randomChoice ) Create () balancer.Balancer {
5353 return RandomChoice ()
5454}
5555
5656func (r * roundRobin ) Next () conn.Conn {
57+ r .mu .RLock ()
58+ defer r .mu .RUnlock ()
5759 if n := len (r .conns ); n == 0 {
5860 return nil
5961 }
@@ -63,23 +65,27 @@ func (r *roundRobin) Next() conn.Conn {
6365}
6466
6567func (r * randomChoice ) Next () conn.Conn {
68+ r .mu .RLock ()
69+ defer r .mu .RUnlock ()
6670 if n := len (r .conns ); n == 0 {
6771 return nil
6872 }
69- r .m .Lock ()
7073 i := r .belt [r .r .Int (len (r .belt ))]
71- r .m .Unlock ()
7274 return r .conns [i ].Conn
7375}
7476
7577func (r * roundRobin ) Insert (conn conn.Conn ) balancer.Element {
78+ r .mu .Lock ()
79+ defer r .mu .Unlock ()
7680 e := r .conns .Insert (conn )
7781 r .updateMinMax (e .Conn )
7882 r .belt = r .distribute ()
7983 return e
8084}
8185
8286func (r * roundRobin ) Remove (x balancer.Element ) bool {
87+ r .mu .Lock ()
88+ defer r .mu .Unlock ()
8389 el := x .(* list.Element )
8490 r .conns .Remove (el )
8591 r .inspectMinMax (el .Conn .Endpoint ().LoadFactor ())
@@ -88,6 +94,8 @@ func (r *roundRobin) Remove(x balancer.Element) bool {
8894}
8995
9096func (r * roundRobin ) Contains (x balancer.Element ) bool {
97+ r .mu .RLock ()
98+ defer r .mu .RUnlock ()
9199 if x == nil {
92100 return false
93101 }
@@ -98,6 +106,7 @@ func (r *roundRobin) Contains(x balancer.Element) bool {
98106 return r .conns .Contains (el )
99107}
100108
109+ // r.mu must be held
101110func (r * roundRobin ) updateMinMax (cc conn.Conn ) {
102111 if len (r .conns ) == 1 {
103112 r .min = cc .Endpoint ().LoadFactor ()
@@ -112,6 +121,7 @@ func (r *roundRobin) updateMinMax(cc conn.Conn) {
112121 }
113122}
114123
124+ // r.mu must be held
115125func (r * roundRobin ) inspectMinMax (loadFactor float32 ) {
116126 if r .min != loadFactor && r .max != loadFactor {
117127 return
@@ -133,13 +143,15 @@ func (r *roundRobin) inspectMinMax(loadFactor float32) {
133143 }
134144}
135145
146+ // r.mu must be held
136147func (r * roundRobin ) distribute () []int {
137148 return r .spread (distribution (
138149 r .min , int32 (len (r .conns )),
139150 r .max , 1 ,
140151 ))
141152}
142153
154+ // r.mu must be held
143155func (r * roundRobin ) spread (f func (float32 ) int32 ) []int {
144156 var (
145157 dist = make ([]int32 , 0 , len (r .conns ))
@@ -244,13 +256,3 @@ func (h *distItemsHeap) Pop() interface{} {
244256 * h = p [:n - 1 ]
245257 return x
246258}
247-
248- func IsRoundRobin (i interface {}) bool {
249- _ , ok := i .(* roundRobin )
250- return ok
251- }
252-
253- func IsRandomChoice (i interface {}) bool {
254- _ , ok := i .(* randomChoice )
255- return ok
256- }
0 commit comments