grpcrand: delete all of grpcrand and call the rand package directly (#7283)

This commit is contained in:
Arvind Bright 2024-05-31 11:32:53 -07:00 committed by GitHub
parent 24e9024375
commit 8bf2b3ee6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 82 additions and 251 deletions

View File

@ -29,6 +29,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"sync"
"sync/atomic"
@ -36,7 +37,6 @@ import (
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/internal/balancer/gracefulswitch"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
)
@ -234,7 +234,7 @@ func (es *endpointSharding) updateState() {
p := &pickerWithChildStates{
pickers: pickers,
childStates: childStates,
next: uint32(grpcrand.Intn(len(pickers))),
next: uint32(rand.Intn(len(pickers))),
}
es.cc.UpdateState(balancer.State{
ConnectivityState: aggState,

View File

@ -19,13 +19,13 @@
package grpclb
import (
"math/rand"
"sync"
"sync/atomic"
"google.golang.org/grpc/balancer"
lbpb "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/status"
)
@ -112,7 +112,7 @@ type rrPicker struct {
func newRRPicker(readySCs []balancer.SubConn) *rrPicker {
return &rrPicker{
subConns: readySCs,
subConnsNext: grpcrand.Intn(len(readySCs)),
subConnsNext: rand.Intn(len(readySCs)),
}
}
@ -147,7 +147,7 @@ func newLBPicker(serverList []*lbpb.Server, readySCs []balancer.SubConn, stats *
return &lbPicker{
serverList: serverList,
subConns: readySCs,
subConnsNext: grpcrand.Intn(len(readySCs)),
subConnsNext: rand.Intn(len(readySCs)),
stats: stats,
}
}

View File

@ -194,13 +194,13 @@ func checkRoundRobinRPCs(ctx context.Context, client testgrpc.TestServiceClient,
// deterministic, allowing the test to make assertions on the distribution.
func (s) TestLeastRequestE2E(t *testing.T) {
defer func(u func() uint32) {
grpcranduint32 = u
}(grpcranduint32)
randuint32 = u
}(randuint32)
var index int
indexes := []uint32{
0, 0, 1, 1, 2, 2, // Triggers a round robin distribution.
}
grpcranduint32 = func() uint32 {
randuint32 = func() uint32 {
ret := indexes[index%len(indexes)]
index++
return ret
@ -310,13 +310,13 @@ func (s) TestLeastRequestE2E(t *testing.T) {
// previous. Any created streams should then be started on the new backend.
func (s) TestLeastRequestPersistsCounts(t *testing.T) {
defer func(u func() uint32) {
grpcranduint32 = u
}(grpcranduint32)
randuint32 = u
}(randuint32)
var index int
indexes := []uint32{
0, 0, 1, 1,
}
grpcranduint32 = func() uint32 {
randuint32 = func() uint32 {
ret := indexes[index%len(indexes)]
index++
return ret

View File

@ -22,17 +22,17 @@ package leastrequest
import (
"encoding/json"
"fmt"
"math/rand"
"sync/atomic"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/serviceconfig"
)
// grpcranduint32 is a global to stub out in tests.
var grpcranduint32 = grpcrand.Uint32
// randuint32 is a global to stub out in tests.
var randuint32 = rand.Uint32
// Name is the name of the least request balancer.
const Name = "least_request_experimental"
@ -157,7 +157,7 @@ func (p *picker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
var pickedSC *scWithRPCCount
var pickedSCNumRPCs int32
for i := 0; i < int(p.choiceCount); i++ {
index := grpcranduint32() % uint32(len(p.subConns))
index := randuint32() % uint32(len(p.subConns))
sc := p.subConns[index]
n := sc.numRPCs.Load()
if pickedSC == nil || n < pickedSCNumRPCs {

View File

@ -23,12 +23,13 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal"
internalgrpclog "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/pretty"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
@ -36,6 +37,7 @@ import (
func init() {
balancer.Register(pickfirstBuilder{})
internal.ShuffleAddressListForTesting = func(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
}
var logger = grpclog.Component("pick-first-lb")
@ -101,6 +103,12 @@ func (b *pickfirstBalancer) ResolverError(err error) {
})
}
type Shuffler interface {
ShuffleAddressListForTesting(n int, swap func(i, j int))
}
func ShuffleAddressListForTesting(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 {
// The resolver reported an empty address list. Treat it like an error by
@ -132,7 +140,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
// within each endpoint. - A61
if cfg.ShuffleAddressList {
endpoints = append([]resolver.Endpoint{}, endpoints...)
grpcrand.Shuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
internal.ShuffleAddressListForTesting.(func(int, func(int, int)))(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
}
// "Flatten the list by concatenating the ordered list of addresses for each
@ -153,7 +161,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
addrs = state.ResolverState.Addresses
if cfg.ShuffleAddressList {
addrs = append([]resolver.Address{}, addrs...)
grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] })
rand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] })
}
}

View File

@ -20,16 +20,15 @@
package adaptive
import (
"math/rand"
"sync"
"time"
"google.golang.org/grpc/internal/grpcrand"
)
// For overriding in unittests.
var (
timeNowFunc = func() time.Time { return time.Now() }
randFunc = func() float64 { return grpcrand.Float64() }
randFunc = func() float64 { return rand.Float64() }
)
const (

View File

@ -22,12 +22,12 @@
package roundrobin
import (
"math/rand"
"sync/atomic"
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/balancer/base"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/grpcrand"
)
// Name is the name of round_robin balancer.
@ -60,7 +60,7 @@ func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker {
// Start at a random index, as the same RR balancer rebuilds a new
// picker when SubConn states change, and we don't want to apply excess
// load to the first server in the list.
next: uint32(grpcrand.Intn(len(scs))),
next: uint32(rand.Intn(len(scs))),
}
}

View File

@ -23,6 +23,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math/rand"
"sync"
"sync/atomic"
"time"
@ -33,7 +34,6 @@ import (
"google.golang.org/grpc/balancer/weightedroundrobin/internal"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
iserviceconfig "google.golang.org/grpc/internal/serviceconfig"
"google.golang.org/grpc/orca"
"google.golang.org/grpc/resolver"
@ -318,7 +318,7 @@ func (b *wrrBalancer) regeneratePicker() {
}
p := &picker{
v: grpcrand.Uint32(), // start the scheduler at a random point
v: rand.Uint32(), // start the scheduler at a random point
cfg: b.cfg,
subConns: b.readySubConns(),
}

View File

@ -22,6 +22,7 @@ import (
"context"
"flag"
"math"
"math/rand"
"runtime"
"sync"
"time"
@ -32,7 +33,6 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/syscall"
"google.golang.org/grpc/status"
"google.golang.org/grpc/testdata"
@ -298,7 +298,7 @@ func (bc *benchmarkClient) unaryLoop(conns []*grpc.ClientConn, rpcCountPerConn i
}
}
} else { // Open loop.
timeBetweenRPCs := time.Duration((grpcrand.ExpFloat64() / *poissonLambda) * float64(time.Second))
timeBetweenRPCs := time.Duration((rand.ExpFloat64() / *poissonLambda) * float64(time.Second))
time.AfterFunc(timeBetweenRPCs, func() {
bc.poissonUnary(client, idx, reqSize, respSize, *poissonLambda)
})
@ -348,7 +348,7 @@ func (bc *benchmarkClient) streamingLoop(conns []*grpc.ClientConn, rpcCountPerCo
}
}(idx)
} else { // Open loop.
timeBetweenRPCs := time.Duration((grpcrand.ExpFloat64() / *poissonLambda) * float64(time.Second))
timeBetweenRPCs := time.Duration((rand.ExpFloat64() / *poissonLambda) * float64(time.Second))
time.AfterFunc(timeBetweenRPCs, func() {
bc.poissonStreaming(stream, idx, reqSize, respSize, *poissonLambda, doRPC)
})
@ -366,7 +366,7 @@ func (bc *benchmarkClient) poissonUnary(client testgrpc.BenchmarkServiceClient,
elapse := time.Since(start)
bc.lockingHistograms[idx].add(int64(elapse))
}()
timeBetweenRPCs := time.Duration((grpcrand.ExpFloat64() / lambda) * float64(time.Second))
timeBetweenRPCs := time.Duration((rand.ExpFloat64() / lambda) * float64(time.Second))
time.AfterFunc(timeBetweenRPCs, func() {
bc.poissonUnary(client, idx, reqSize, respSize, lambda)
})
@ -381,7 +381,7 @@ func (bc *benchmarkClient) poissonStreaming(stream testgrpc.BenchmarkService_Str
elapse := time.Since(start)
bc.lockingHistograms[idx].add(int64(elapse))
}()
timeBetweenRPCs := time.Duration((grpcrand.ExpFloat64() / lambda) * float64(time.Second))
timeBetweenRPCs := time.Duration((rand.ExpFloat64() / lambda) * float64(time.Second))
time.AfterFunc(timeBetweenRPCs, func() {
bc.poissonStreaming(stream, idx, reqSize, respSize, lambda, doRPC)
})

View File

@ -22,12 +22,12 @@ package main
import (
"context"
"log"
"math/rand"
"net"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/channelz/service"
"google.golang.org/grpc/internal/grpcrand"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
@ -54,7 +54,7 @@ type slowServer struct {
// SayHello implements helloworld.GreeterServer
func (s *slowServer) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
// Delay 100ms ~ 200ms before replying
time.Sleep(time.Duration(100+grpcrand.Intn(100)) * time.Millisecond)
time.Sleep(time.Duration(100+rand.Intn(100)) * time.Millisecond)
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

View File

@ -25,10 +25,10 @@ package backoff
import (
"context"
"errors"
"math/rand"
"time"
grpcbackoff "google.golang.org/grpc/backoff"
"google.golang.org/grpc/internal/grpcrand"
)
// Strategy defines the methodology for backing off after a grpc connection
@ -67,7 +67,7 @@ func (bc Exponential) Backoff(retries int) time.Duration {
}
// Randomize backoff delays so that if a cluster of requests start at
// the same time, they won't operate in lockstep.
backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1)
backoff *= 1 + bc.Config.Jitter*(rand.Float64()*2-1)
if backoff < 0 {
return 0
}

View File

@ -1,100 +0,0 @@
//go:build !go1.21
// TODO: when this file is deleted (after Go 1.20 support is dropped), delete
// all of grpcrand and call the rand package directly.
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package grpcrand implements math/rand functions in a concurrent-safe way
// with a global random source, independent of math/rand's global source.
package grpcrand
import (
"math/rand"
"sync"
"time"
)
var (
r = rand.New(rand.NewSource(time.Now().UnixNano()))
mu sync.Mutex
)
// Int implements rand.Int on the grpcrand global source.
func Int() int {
mu.Lock()
defer mu.Unlock()
return r.Int()
}
// Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 {
mu.Lock()
defer mu.Unlock()
return r.Int63n(n)
}
// Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int {
mu.Lock()
defer mu.Unlock()
return r.Intn(n)
}
// Int31n implements rand.Int31n on the grpcrand global source.
func Int31n(n int32) int32 {
mu.Lock()
defer mu.Unlock()
return r.Int31n(n)
}
// Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 {
mu.Lock()
defer mu.Unlock()
return r.Float64()
}
// Uint64 implements rand.Uint64 on the grpcrand global source.
func Uint64() uint64 {
mu.Lock()
defer mu.Unlock()
return r.Uint64()
}
// Uint32 implements rand.Uint32 on the grpcrand global source.
func Uint32() uint32 {
mu.Lock()
defer mu.Unlock()
return r.Uint32()
}
// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source.
func ExpFloat64() float64 {
mu.Lock()
defer mu.Unlock()
return r.ExpFloat64()
}
// Shuffle implements rand.Shuffle on the grpcrand global source.
var Shuffle = func(n int, f func(int, int)) {
mu.Lock()
defer mu.Unlock()
r.Shuffle(n, f)
}

View File

@ -1,73 +0,0 @@
//go:build go1.21
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package grpcrand implements math/rand functions in a concurrent-safe way
// with a global random source, independent of math/rand's global source.
package grpcrand
import "math/rand"
// This implementation will be used for Go version 1.21 or newer.
// For older versions, the original implementation with mutex will be used.
// Int implements rand.Int on the grpcrand global source.
func Int() int {
return rand.Int()
}
// Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 {
return rand.Int63n(n)
}
// Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int {
return rand.Intn(n)
}
// Int31n implements rand.Int31n on the grpcrand global source.
func Int31n(n int32) int32 {
return rand.Int31n(n)
}
// Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 {
return rand.Float64()
}
// Uint64 implements rand.Uint64 on the grpcrand global source.
func Uint64() uint64 {
return rand.Uint64()
}
// Uint32 implements rand.Uint32 on the grpcrand global source.
func Uint32() uint32 {
return rand.Uint32()
}
// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source.
func ExpFloat64() float64 {
return rand.ExpFloat64()
}
// Shuffle implements rand.Shuffle on the grpcrand global source.
var Shuffle = func(n int, f func(int, int)) {
rand.Shuffle(n, f)
}

View File

@ -211,6 +211,10 @@ var (
// UserSetDefaultScheme is set to true if the user has overridden the
// default resolver scheme.
UserSetDefaultScheme bool = false
// ShuffleAddressListForTesting pseudo-randomizes the order of addresses. n
// is the number of elements. swap swaps the elements with indexes i and j.
ShuffleAddressListForTesting any // func(n int, swap func(i, j int))
)
// HealthChecker defines the signature of the client-side LB channel health

View File

@ -24,6 +24,7 @@ import (
"context"
"encoding/json"
"fmt"
"math/rand"
"net"
"os"
"strconv"
@ -35,7 +36,6 @@ import (
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/resolver/dns/internal"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/serviceconfig"
@ -423,7 +423,7 @@ func chosenByPercentage(a *int) bool {
if a == nil {
return true
}
return grpcrand.Intn(100)+1 <= *a
return rand.Intn(100)+1 <= *a
}
func canaryingSC(js string) string {

View File

@ -21,11 +21,10 @@ package serviceconfig
import (
"fmt"
"math"
"math/rand"
"strings"
"testing"
"time"
"google.golang.org/grpc/internal/grpcrand"
)
// Tests both marshalling and unmarshalling of Durations.
@ -69,7 +68,7 @@ func TestDuration_MarshalUnmarshal(t *testing.T) {
for _, tc := range testCases {
// Seed `got` with a random value to ensure we properly reset it in all
// non-error cases.
got := Duration(grpcrand.Uint64())
got := Duration(rand.Uint64())
err := got.UnmarshalJSON([]byte(tc.json))
if (err == nil && time.Duration(got) != tc.td) ||
(err != nil) != (tc.unmarshalErr != nil) || !strings.Contains(fmt.Sprint(err), fmt.Sprint(tc.unmarshalErr)) {

View File

@ -25,6 +25,7 @@ import (
"fmt"
"io"
"math"
"math/rand"
"net"
"net/http"
"strconv"
@ -43,7 +44,6 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata"
@ -1440,7 +1440,7 @@ func getJitter(v time.Duration) time.Duration {
}
// Generate a jitter between +/- 10% of the value.
r := int64(v / 10)
j := grpcrand.Int63n(2*r) - r
j := rand.Int63n(2*r) - r
return time.Duration(j)
}

View File

@ -19,9 +19,8 @@ package wrr
import (
"fmt"
"math/rand"
"sort"
"google.golang.org/grpc/internal/grpcrand"
)
// weightedItem is a wrapped weighted item that is used to implement weighted random algorithm.
@ -47,19 +46,19 @@ func NewRandom() WRR {
return &randomWRR{}
}
var grpcrandInt63n = grpcrand.Int63n
var randInt63n = rand.Int63n
func (rw *randomWRR) Next() (item any) {
if len(rw.items) == 0 {
return nil
}
if rw.equalWeights {
return rw.items[grpcrandInt63n(int64(len(rw.items)))].item
return rw.items[randInt63n(int64(len(rw.items)))].item
}
sumOfWeights := rw.items[len(rw.items)-1].accumulatedWeight
// Random number in [0, sumOfWeights).
randomWeight := grpcrandInt63n(sumOfWeights)
randomWeight := randInt63n(sumOfWeights)
// Item's accumulated weights are in ascending order, because item's weight >= 0.
// Binary search rw.items to find first item whose accumulatedWeight > randomWeight
// The return i is guaranteed to be in range [0, len(rw.items)) because randomWeight < last item's accumulatedWeight

View File

@ -189,5 +189,5 @@ func BenchmarkRandomWRRNext(b *testing.B) {
func init() {
r := rand.New(rand.NewSource(0))
grpcrandInt63n = r.Int63n
randInt63n = r.Int63n
}

View File

@ -54,10 +54,6 @@ git grep --quiet 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark
# timer since there is no way to stop it early.
git grep --quiet -l 'time.After(' -- "*.go" | not grep -v '_test.go\|test_utils\|testutils'
# - Do not import math/rand for real library code. Use internal/grpcrand for
# thread safety.
git grep --quiet -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test'
# - Do not use "interface{}"; use "any" instead.
git grep --quiet -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc\|grpc_testing_not_regenerate'

View File

@ -23,6 +23,7 @@ import (
"errors"
"io"
"math"
"math/rand"
"strconv"
"sync"
"time"
@ -34,7 +35,6 @@ import (
"google.golang.org/grpc/internal/balancerload"
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcutil"
imetadata "google.golang.org/grpc/internal/metadata"
iresolver "google.golang.org/grpc/internal/resolver"
@ -699,7 +699,7 @@ func (a *csAttempt) shouldRetry(err error) (bool, error) {
if max := float64(rp.MaxBackoff); cur > max {
cur = max
}
dur = time.Duration(grpcrand.Int63n(int64(cur)))
dur = time.Duration(rand.Int63n(int64(cur)))
cs.numRetriesSincePushback++
}

View File

@ -33,7 +33,6 @@ import (
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/stubserver"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/grpc/internal/testutils/pickfirst"
@ -378,9 +377,9 @@ func (s) TestPickFirst_ShuffleAddressList(t *testing.T) {
const serviceConfig = `{"loadBalancingConfig": [{"pick_first":{ "shuffleAddressList": true }}]}`
// Install a shuffler that always reverses two entries.
origShuf := grpcrand.Shuffle
defer func() { grpcrand.Shuffle = origShuf }()
grpcrand.Shuffle = func(n int, f func(int, int)) {
origShuf := internal.ShuffleAddressListForTesting
defer func() { internal.ShuffleAddressListForTesting = origShuf }()
internal.ShuffleAddressListForTesting = func(n int, f func(int, int)) {
if n != 2 {
t.Errorf("Shuffle called with n=%v; want 2", n)
return
@ -435,9 +434,9 @@ func (s) TestPickFirst_ShuffleAddressList(t *testing.T) {
// Test config parsing with the env var turned on and off for various scenarios.
func (s) TestPickFirst_ParseConfig_Success(t *testing.T) {
// Install a shuffler that always reverses two entries.
origShuf := grpcrand.Shuffle
defer func() { grpcrand.Shuffle = origShuf }()
grpcrand.Shuffle = func(n int, f func(int, int)) {
origShuf := internal.ShuffleAddressListForTesting
defer func() { internal.ShuffleAddressListForTesting = origShuf }()
internal.ShuffleAddressListForTesting = func(n int, f func(int, int)) {
if n != 2 {
t.Errorf("Shuffle called with n=%v; want 2", n)
return

View File

@ -27,6 +27,7 @@ package googledirectpath
import (
"fmt"
"math/rand"
"net/url"
"time"
@ -34,7 +35,6 @@ import (
"google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/googlecloud"
internalgrpclog "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/xds/bootstrap"
"google.golang.org/grpc/resolver"
"google.golang.org/grpc/xds/internal/xdsclient"
@ -159,7 +159,7 @@ func (r *c2pResolver) Close() {
r.clientCloseFunc()
}
var id = fmt.Sprintf("C2P-%d", grpcrand.Int())
var id = fmt.Sprintf("C2P-%d", rand.Int())
func newNodeConfig(zone string, ipv6Capable bool) string {
metadata := ""

View File

@ -25,6 +25,7 @@ import (
"encoding/json"
"fmt"
"math"
"math/rand"
"strings"
"sync"
"sync/atomic"
@ -37,7 +38,6 @@ import (
"google.golang.org/grpc/internal/buffer"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync"
iserviceconfig "google.golang.org/grpc/internal/serviceconfig"
"google.golang.org/grpc/resolver"
@ -838,7 +838,7 @@ func (b *outlierDetectionBalancer) successRateAlgorithm() {
requiredSuccessRate := mean - stddev*(float64(ejectionCfg.StdevFactor)/1000)
if successRate < requiredSuccessRate {
channelz.Infof(logger, b.channelzParent, "SuccessRate algorithm detected outlier: %s. Parameters: successRate=%f, mean=%f, stddev=%f, requiredSuccessRate=%f", addrInfo, successRate, mean, stddev, requiredSuccessRate)
if uint32(grpcrand.Int31n(100)) < ejectionCfg.EnforcementPercentage {
if uint32(rand.Int31n(100)) < ejectionCfg.EnforcementPercentage {
b.ejectAddress(addrInfo)
}
}
@ -865,7 +865,7 @@ func (b *outlierDetectionBalancer) failurePercentageAlgorithm() {
failurePercentage := (float64(bucket.numFailures) / float64(bucket.numSuccesses+bucket.numFailures)) * 100
if failurePercentage > float64(b.cfg.FailurePercentageEjection.Threshold) {
channelz.Infof(logger, b.channelzParent, "FailurePercentage algorithm detected outlier: %s, failurePercentage=%f", addrInfo, failurePercentage)
if uint32(grpcrand.Int31n(100)) < ejectionCfg.EnforcementPercentage {
if uint32(rand.Int31n(100)) < ejectionCfg.EnforcementPercentage {
b.ejectAddress(addrInfo)
}
}

View File

@ -24,12 +24,12 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"strconv"
"sync/atomic"
"time"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/internal/grpcrand"
iresolver "google.golang.org/grpc/internal/resolver"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
@ -162,7 +162,7 @@ func (i *interceptor) NewStream(ctx context.Context, ri iresolver.RPCInfo, done
}
// For overriding in tests
var randIntn = grpcrand.Intn
var randIntn = rand.Intn
var newTimer = time.NewTimer
func injectDelay(ctx context.Context, delayCfg *cpb.FaultDelay) error {

View File

@ -26,6 +26,7 @@ import (
"context"
"fmt"
"io"
"math/rand"
"net"
"reflect"
"testing"
@ -35,7 +36,6 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpctest"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/grpc/internal/testutils/xds/bootstrap"
@ -483,7 +483,7 @@ func (s) TestFaultInjection_Unary(t *testing.T) {
for tcNum, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
defer func() { randIntn = grpcrand.Intn; newTimer = time.NewTimer }()
defer func() { randIntn = rand.Intn; newTimer = time.NewTimer }()
var intnCalls []int
var newTimerCalls []time.Duration
randOut := 0

View File

@ -23,13 +23,13 @@ import (
"encoding/json"
"fmt"
"math/bits"
"math/rand"
"strings"
"sync/atomic"
"time"
xxhash "github.com/cespare/xxhash/v2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcutil"
iresolver "google.golang.org/grpc/internal/resolver"
"google.golang.org/grpc/internal/serviceconfig"
@ -274,7 +274,7 @@ func (cs *configSelector) generateHash(rpcInfo iresolver.RPCInfo, hashPolicies [
}
// If no generated hash return a random long. In the grand scheme of things
// this logically will map to choosing a random backend to route request to.
return grpcrand.Uint64()
return rand.Uint64()
}
func (cs *configSelector) newInterceptor(rt *route, cluster *routeCluster) (iresolver.ClientInterceptor, error) {

View File

@ -22,11 +22,11 @@ package resolver
import (
"context"
"fmt"
"math/rand"
"sync/atomic"
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/pretty"
iresolver "google.golang.org/grpc/internal/resolver"
@ -75,7 +75,7 @@ func (b *xdsResolverBuilder) Build(target resolver.Target, cc resolver.ClientCon
r := &xdsResolver{
cc: cc,
activeClusters: make(map[string]*clusterInfo),
channelID: grpcrand.Uint64(),
channelID: rand.Uint64(),
}
defer func() {
if retErr != nil {

View File

@ -19,9 +19,9 @@ package xdsresource
import (
"fmt"
"math/rand"
"strings"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcutil"
iresolver "google.golang.org/grpc/internal/resolver"
"google.golang.org/grpc/internal/xds/matcher"
@ -142,8 +142,8 @@ func newFractionMatcher(fraction uint32) *fractionMatcher {
return &fractionMatcher{fraction: int64(fraction)}
}
// RandInt63n overwrites grpcrand for control in tests.
var RandInt63n = grpcrand.Int63n
// RandInt63n overwrites rand for control in tests.
var RandInt63n = rand.Int63n
func (fm *fractionMatcher) match() bool {
t := RandInt63n(1000000)

View File

@ -19,10 +19,10 @@ package xdsresource
import (
"context"
"math/rand"
"testing"
"github.com/google/go-cmp/cmp"
"google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcutil"
iresolver "google.golang.org/grpc/internal/resolver"
"google.golang.org/grpc/internal/xds/matcher"
@ -119,7 +119,7 @@ func (s) TestFractionMatcherMatch(t *testing.T) {
const fraction = 500000
fm := newFractionMatcher(fraction)
defer func() {
RandInt63n = grpcrand.Int63n
RandInt63n = rand.Int63n
}()
// rand > fraction, should return false.