mirror of https://github.com/grpc/grpc-go.git
grpcrand: delete all of grpcrand and call the rand package directly (#7283)
This commit is contained in:
parent
24e9024375
commit
8bf2b3ee6e
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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] })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -189,5 +189,5 @@ func BenchmarkRandomWRRNext(b *testing.B) {
|
|||
|
||||
func init() {
|
||||
r := rand.New(rand.NewSource(0))
|
||||
grpcrandInt63n = r.Int63n
|
||||
randInt63n = r.Int63n
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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++
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 := ""
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue