Use a sync.Pool to remove the global random bottleneck in picking a random conn

This commit is contained in:
Andy Wang 2020-12-26 13:48:42 +00:00
parent 415523f10a
commit 2d08e88efb
No known key found for this signature in database
GPG Key ID: 181B49F9F38F3374
1 changed files with 8 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
"net" "net"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
) )
const ( const (
@ -31,6 +32,7 @@ type switchboard struct {
conns sync.Map conns sync.Map
numConns uint32 numConns uint32
nextConnId uint32 nextConnId uint32
randPool sync.Pool
broken uint32 broken uint32
} }
@ -48,6 +50,9 @@ func makeSwitchboard(sesh *Session) *switchboard {
strategy: strategy, strategy: strategy,
valve: sesh.Valve, valve: sesh.Valve,
nextConnId: 1, nextConnId: 1,
randPool: sync.Pool{New: func() interface{} {
return rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
}},
} }
return sb return sb
} }
@ -121,7 +126,9 @@ func (sb *switchboard) pickRandConn() (uint32, net.Conn, error) {
// so if the r > len(sb.conns) at the point of range call, the last visited element is picked // so if the r > len(sb.conns) at the point of range call, the last visited element is picked
var id uint32 var id uint32
var conn net.Conn var conn net.Conn
r := rand.Intn(connCount) randReader := sb.randPool.Get().(*rand.Rand)
r := randReader.Intn(connCount)
sb.randPool.Put(randReader)
var c int var c int
sb.conns.Range(func(connIdI, connI interface{}) bool { sb.conns.Range(func(connIdI, connI interface{}) bool {
if r == c { if r == c {