From 98307b480b0eb52a83fcb6f96225c1196a0873a9 Mon Sep 17 00:00:00 2001 From: Evan Cordell Date: Mon, 27 Dec 2021 09:07:49 -0500 Subject: [PATCH] balancer: protect rand source with a mutex --- pkg/balancer/hashring.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/balancer/hashring.go b/pkg/balancer/hashring.go index 3f0c90b305..62044966ea 100644 --- a/pkg/balancer/hashring.go +++ b/pkg/balancer/hashring.go @@ -2,6 +2,7 @@ package balancer import ( "math/rand" + "sync" "time" "google.golang.org/grpc/balancer" @@ -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. @@ -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) { @@ -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