Skip to content

Commit 32273f9

Browse files
committed
revert math/rand
1 parent d0af782 commit 32273f9

File tree

11 files changed

+146
-57
lines changed

11 files changed

+146
-57
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 3.11.11
2+
* Reverted usage of `math/rand` (instead `crypto/rand`)
3+
14
## 3.11.10
25
* Imported tool gtrace to `./cmd/gtrace`
36
* Changed minimal version of go from 1.13 to 1.14

internal/balancer/rr/rr.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type roundRobin struct {
2424
belt []int
2525
next int32
2626
conns list.List
27+
r rand.Rand
2728
}
2829

2930
func (r *roundRobin) Create() balancer.Balancer {
@@ -33,15 +34,22 @@ func (r *roundRobin) Create() balancer.Balancer {
3334
belt: r.belt,
3435
next: r.next,
3536
conns: r.conns,
37+
r: rand.New(),
3638
}
3739
}
3840

3941
func RoundRobin() balancer.Balancer {
40-
return &roundRobin{}
42+
return &roundRobin{
43+
r: rand.New(),
44+
}
4145
}
4246

4347
func RandomChoice() balancer.Balancer {
44-
return &randomChoice{}
48+
return &randomChoice{
49+
roundRobin: roundRobin{
50+
r: rand.New(),
51+
},
52+
}
4553
}
4654

4755
type randomChoice struct {
@@ -51,7 +59,14 @@ type randomChoice struct {
5159

5260
func (r *randomChoice) Create() balancer.Balancer {
5361
return &randomChoice{
54-
roundRobin: *(r.roundRobin.Create().(*roundRobin)),
62+
roundRobin: roundRobin{
63+
min: r.roundRobin.min,
64+
max: r.roundRobin.max,
65+
belt: r.roundRobin.belt,
66+
next: r.roundRobin.next,
67+
conns: r.roundRobin.conns,
68+
r: rand.New(),
69+
},
5570
}
5671
}
5772

@@ -69,7 +84,7 @@ func (r *randomChoice) Next() conn.Conn {
6984
return nil
7085
}
7186
r.m.Lock()
72-
i := r.belt[rand.Int(len(r.belt))]
87+
i := r.belt[r.r.Int(len(r.belt))]
7388
r.m.Unlock()
7489
return r.conns[i].Conn
7590
}

internal/meta/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package meta
22

33
const (
4-
Version = "ydb-go-sdk/3.11.10"
4+
Version = "ydb-go-sdk/3.11.11"
55
)

internal/rand/rand.go

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
11
package rand
22

33
import (
4-
"crypto/rand"
5-
"math/big"
4+
"math"
5+
"math/rand"
6+
"sync"
67
)
78

8-
func int64n(max int64) int64 {
9-
n, err := rand.Int(rand.Reader, big.NewInt(max))
10-
if err != nil {
11-
panic(err) // err on negative max
9+
type Rand interface {
10+
Int64(max int64) int64
11+
Int(max int) int
12+
}
13+
14+
type r struct {
15+
r *rand.Rand
16+
m *sync.Mutex
17+
}
18+
19+
type option func(r *r)
20+
21+
func WithLock() option {
22+
return func(r *r) {
23+
r.m = &sync.Mutex{}
24+
}
25+
}
26+
27+
func New(opts ...option) Rand {
28+
r := &r{
29+
// nolint:gosec
30+
r: rand.New(rand.NewSource(math.MaxInt64)),
31+
}
32+
for _, o := range opts {
33+
o(r)
34+
}
35+
return r
36+
}
37+
38+
func (r *r) int64n(max int64) int64 {
39+
if r.m != nil {
40+
r.m.Lock()
41+
defer r.m.Unlock()
1242
}
13-
return n.Int64()
43+
return r.r.Int63n(max)
1444
}
1545

16-
func Int64(max int64) int64 {
17-
return int64n(max)
46+
func (r *r) Int64(max int64) int64 {
47+
return r.int64n(max)
1848
}
1949

20-
func Int(max int) int {
21-
return int(int64n(int64(max)))
50+
func (r *r) Int(max int) int {
51+
return int(r.int64n(int64(max)))
2252
}

internal/repeater/test/repeat_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ func TestRepeaterCancellation(t *testing.T) {
4848
enter = make(chan struct{}, 2)
4949
exit = make(chan struct{}, 2)
5050
)
51+
5152
timer := timetest.Timer{
5253
Ch: timerC,
5354
}
55+
5456
cleanup := timeutil.StubTestHookNewTimer(func(time.Duration) timeutil.Timer {
5557
return timer
5658
})
@@ -59,13 +61,16 @@ func TestRepeaterCancellation(t *testing.T) {
5961
ctx, cancel := context.WithCancel(context.Background())
6062
defer cancel()
6163

62-
r := repeater.NewRepeater(ctx, 42*time.Second,
64+
r := repeater.NewRepeater(
65+
ctx,
66+
42*time.Second,
6367
func(ctx context.Context) error {
6468
enter <- struct{}{}
6569
<-ctx.Done()
6670
exit <- struct{}{}
6771
return nil
68-
})
72+
},
73+
)
6974

7075
// Run callback in a separate goroutine to avoid deadlock.
7176
// That is, StubTimer run its function in the same goroutine as Emit

internal/table/client_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ func TestSessionPoolCreateAbnormalResult(t *testing.T) {
5353
defer func() {
5454
_ = p.Close(context.Background())
5555
}()
56+
r := rand.New(rand.WithLock())
5657
errCh := make(chan error, limit*10)
5758
fn := func(wg *sync.WaitGroup) {
5859
defer wg.Done()
5960
childCtx, childCancel := context.WithTimeout(
6061
ctx,
61-
time.Duration(rand.Int64(int64(time.Minute))),
62+
time.Duration(r.Int64(int64(time.Minute))),
6263
)
6364
defer childCancel()
6465
s, err := p.createSession(childCtx)

internal/table/retry_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ func TestRetryContextDeadline(t *testing.T) {
301301
p := SessionProviderFunc{
302302
OnGet: client.createSession,
303303
}
304+
r := rand.New(rand.WithLock())
304305
for i := range timeouts {
305306
for j := range sleeps {
306307
timeout := timeouts[i]
@@ -339,7 +340,7 @@ func TestRetryContextDeadline(t *testing.T) {
339340
case <-ctx.Done():
340341
return ctx.Err()
341342
case <-time.After(sleep):
342-
return errs[rand.Int(len(errs))]
343+
return errs[r.Int(len(errs))]
343344
}
344345
},
345346
)

internal/table/scanner/scanner_test.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import (
1818
)
1919

2020
// nolint:gocyclo
21-
func valueFromPrimitiveTypeID(c *column) (*Ydb.Value, interface{}) {
22-
rv := rand.Int64(math.MaxInt16)
21+
func valueFromPrimitiveTypeID(c *column, r rand.Rand) (*Ydb.Value, interface{}) {
22+
rv := r.Int64(math.MaxInt16)
2323
switch c.typeID {
2424
case Ydb.Type_BOOL:
2525
v := rv%2 == 1
@@ -443,8 +443,8 @@ func valueFromPrimitiveTypeID(c *column) (*Ydb.Value, interface{}) {
443443
}
444444
}
445445

446-
func getResultSet(count int, col []*column) (r *Ydb.ResultSet, testValues [][]indexed.RequiredOrOptional) {
447-
r = &Ydb.ResultSet{}
446+
func getResultSet(count int, col []*column) (result *Ydb.ResultSet, testValues [][]indexed.RequiredOrOptional) {
447+
result = &Ydb.ResultSet{}
448448
for _, c := range col {
449449
t := &Ydb.Type{
450450
Type: &Ydb.Type_TypeId{
@@ -460,30 +460,31 @@ func getResultSet(count int, col []*column) (r *Ydb.ResultSet, testValues [][]in
460460
},
461461
}
462462
}
463-
r.Columns = append(
464-
r.Columns,
463+
result.Columns = append(
464+
result.Columns,
465465
&Ydb.Column{
466466
Name: c.name,
467467
Type: t,
468468
},
469469
)
470470
}
471471

472+
r := rand.New(rand.WithLock())
472473
testValues = make([][]indexed.RequiredOrOptional, count)
473474
for i := 0; i < count; i++ {
474475
var items []*Ydb.Value
475476
var vals []indexed.RequiredOrOptional
476-
for j := range r.Columns {
477-
v, val := valueFromPrimitiveTypeID(col[j])
477+
for j := range result.Columns {
478+
v, val := valueFromPrimitiveTypeID(col[j], r)
478479
vals = append(vals, val)
479480
items = append(items, v)
480481
}
481-
r.Rows = append(r.Rows, &Ydb.Value{
482+
result.Rows = append(result.Rows, &Ydb.Value{
482483
Items: items,
483484
})
484485
testValues[i] = vals
485486
}
486-
return r, testValues
487+
return result, testValues
487488
}
488489

489490
func TestScanSqlTypes(t *testing.T) {

retry/retry.go

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ const (
1818

1919
// Default parameters used by Retry() functions within different sub packages.
2020
var (
21-
FastBackoff = logBackoff{
22-
SlotDuration: fastSlot,
23-
Ceiling: 6,
24-
}
25-
SlowBackoff = logBackoff{
26-
SlotDuration: slowSlot,
27-
Ceiling: 6,
28-
}
21+
FastBackoff = newBackoff(
22+
withSlotDuration(fastSlot),
23+
withCeiling(6),
24+
)
25+
SlowBackoff = newBackoff(
26+
withSlotDuration(slowSlot),
27+
withCeiling(6),
28+
)
2929
)
3030

3131
// retryOperation is the interface that holds an operation for retry.
@@ -226,6 +226,39 @@ type logBackoff struct {
226226
// where F is a result of multiplication of this value and calculated delay
227227
// duration D; and R is a random sized part from [0,(D - F)].
228228
JitterLimit float64
229+
230+
// generator of jitter
231+
r rand.Rand
232+
}
233+
234+
type option func(b *logBackoff)
235+
236+
func withSlotDuration(slotDuration time.Duration) option {
237+
return func(b *logBackoff) {
238+
b.SlotDuration = slotDuration
239+
}
240+
}
241+
242+
func withCeiling(ceiling uint) option {
243+
return func(b *logBackoff) {
244+
b.Ceiling = ceiling
245+
}
246+
}
247+
248+
func withJitterLimit(jitterLimit float64) option {
249+
return func(b *logBackoff) {
250+
b.JitterLimit = jitterLimit
251+
}
252+
}
253+
254+
func newBackoff(opts ...option) logBackoff {
255+
b := logBackoff{
256+
r: rand.New(rand.WithLock()),
257+
}
258+
for _, o := range opts {
259+
o(&b)
260+
}
261+
return b
229262
}
230263

231264
// Wait implements Backoff interface.
@@ -245,7 +278,7 @@ func (b logBackoff) delay(i int) time.Duration {
245278
if f == d {
246279
return f
247280
}
248-
return f + time.Duration(rand.Int64(int64(d-f)+1))
281+
return f + time.Duration(b.r.Int64(int64(d-f)+1))
249282
}
250283

251284
func min(a, b uint) uint {

retry/retry_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ func TestLogBackoff(t *testing.T) {
2525
seeds int64
2626
}{
2727
{
28-
backoff: logBackoff{
29-
SlotDuration: time.Second,
30-
Ceiling: 3,
31-
JitterLimit: 0,
32-
},
28+
backoff: newBackoff(
29+
withSlotDuration(time.Second),
30+
withCeiling(3),
31+
withJitterLimit(0),
32+
),
3333
exp: []exp{
3434
{gte: 0, lte: time.Second}, // 1 << min(0, 3)
3535
{gte: 0, lte: 2 * time.Second}, // 1 << min(1, 3)
@@ -42,11 +42,11 @@ func TestLogBackoff(t *testing.T) {
4242
seeds: 1000,
4343
},
4444
{
45-
backoff: logBackoff{
46-
SlotDuration: time.Second,
47-
Ceiling: 3,
48-
JitterLimit: 0.5,
49-
},
45+
backoff: newBackoff(
46+
withSlotDuration(time.Second),
47+
withCeiling(3),
48+
withJitterLimit(0.5),
49+
),
5050
exp: []exp{
5151
{gte: 500 * time.Millisecond, lte: time.Second}, // 1 << min(0, 3)
5252
{gte: 1 * time.Second, lte: 2 * time.Second}, // 1 << min(1, 3)
@@ -59,11 +59,11 @@ func TestLogBackoff(t *testing.T) {
5959
seeds: 1000,
6060
},
6161
{
62-
backoff: logBackoff{
63-
SlotDuration: time.Second,
64-
Ceiling: 3,
65-
JitterLimit: 1,
66-
},
62+
backoff: newBackoff(
63+
withSlotDuration(time.Second),
64+
withCeiling(3),
65+
withJitterLimit(1),
66+
),
6767
exp: []exp{
6868
{eq: time.Second}, // 1 << min(0, 3)
6969
{eq: 2 * time.Second}, // 1 << min(1, 3)

0 commit comments

Comments
 (0)