Skip to content

Commit f778079

Browse files
authored
Merge pull request #430 from qnnn/master
Fix concurrency unsafety error of rand.Intn.
2 parents 2777ea8 + fa16bdc commit f778079

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

runner/calldata.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
htmlTemplate "html/template"
88
"math/rand"
99
"strings"
10+
"sync"
1011
"text/template"
1112
"text/template/parse"
1213
"time"
@@ -19,8 +20,11 @@ import (
1920
const charset = "abcdefghijklmnopqrstuvwxyz" +
2021
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
2122

22-
var seededRand *rand.Rand = rand.New(
23-
rand.NewSource(time.Now().UnixNano()))
23+
var seededRandPool = sync.Pool{
24+
New: func() interface{} {
25+
return rand.New(rand.NewSource(time.Now().UnixNano()))
26+
},
27+
}
2428

2529
var sprigFuncMap htmlTemplate.FuncMap = sprig.FuncMap()
2630

@@ -178,7 +182,10 @@ func (td *CallData) ExecuteData(data string) ([]byte, error) {
178182
if len(data) > 0 {
179183
input := []byte(data)
180184
tpl, err := td.execute(data)
181-
if err == nil && tpl != nil {
185+
if err != nil {
186+
return nil, err
187+
}
188+
if tpl != nil {
182189
input = tpl.Bytes()
183190
}
184191

@@ -227,15 +234,21 @@ const minLen = 2
227234

228235
func stringWithCharset(length int, charset string) string {
229236
b := make([]byte, length)
237+
rng := seededRandPool.Get().(*rand.Rand)
238+
defer seededRandPool.Put(rng)
230239
for i := range b {
231-
b[i] = charset[seededRand.Intn(len(charset))]
240+
b[i] = charset[rng.Intn(len(charset))]
232241
}
233242
return string(b)
234243
}
235244

236245
func randomString(length int) string {
237246
if length <= 0 {
238-
length = seededRand.Intn(maxLen-minLen+1) + minLen
247+
func() {
248+
rng := seededRandPool.Get().(*rand.Rand)
249+
defer seededRandPool.Put(rng)
250+
length = rng.Intn(maxLen-minLen+1) + minLen
251+
}()
239252
}
240253

241254
return stringWithCharset(length, charset)
@@ -249,6 +262,7 @@ func randomInt(min, max int) int {
249262
if max <= 0 {
250263
max = 1
251264
}
252-
253-
return seededRand.Intn(max-min) + min
265+
rng := seededRandPool.Get().(*rand.Rand)
266+
defer seededRandPool.Put(rng)
267+
return rng.Intn(max-min) + min
254268
}

runner/calldata_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,14 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) {
332332
assert.Equal(t, `{"trace_id":"ABCABCABC"}`, string(r))
333333
})
334334
}
335+
336+
func BenchmarkCallData_randomString(b *testing.B) {
337+
b.N = 100000000
338+
b.SetParallelism(1024)
339+
b.RunParallel(func(pb *testing.PB) {
340+
for pb.Next() {
341+
_ = randomString(10)
342+
}
343+
})
344+
b.Logf("pass")
345+
}

0 commit comments

Comments
 (0)