Skip to content

Commit

Permalink
Merge pull request #353 from ecordell/threadsafe-rand
Browse files Browse the repository at this point in the history
balancer: protect rand source with a mutex
  • Loading branch information
ecordell committed Dec 27, 2021
2 parents 1697fb6 + 98307b4 commit 7b4b33a
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions pkg/balancer/hashring.go
Expand Up @@ -2,6 +2,7 @@ package balancer

import (
"math/rand"
"sync"
"time"

"google.golang.org/grpc/balancer"
Expand All @@ -22,10 +23,7 @@ const (
CtxKey ctxKey = "requestKey"
)

var (
logger = grpclog.Component("consistenthashring")
r = rand.New(rand.NewSource(time.Now().UnixNano()))
)
var logger = grpclog.Component("consistenthashring")

// NewConsistentHashringBuilder creates a new balancer.Builder that
// will create a consistent hashring balancer with the given config.
Expand Down Expand Up @@ -75,12 +73,15 @@ func (b *consistentHashringPickerBuilder) Build(info base.PickerBuildInfo) balan
return &consistentHashringPicker{
hashring: hashring,
spread: b.spread,
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
}

type consistentHashringPicker struct {
sync.Mutex
hashring *consistent.Hashring
spread uint8
rand *rand.Rand
}

func (p *consistentHashringPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
Expand All @@ -89,7 +90,13 @@ func (p *consistentHashringPicker) Pick(info balancer.PickInfo) (balancer.PickRe
if err != nil {
return balancer.PickResult{}, err
}
chosen := members[r.Intn(int(p.spread))].(subConnMember)

// rand is not safe for concurrent use
p.Lock()
index := p.rand.Intn(int(p.spread))
p.Unlock()

chosen := members[index].(subConnMember)
return balancer.PickResult{
SubConn: chosen.SubConn,
}, nil
Expand Down

0 comments on commit 7b4b33a

Please sign in to comment.