Skip to content

Commit 9c073bb

Browse files
zuwasiampagent
andauthored
fix(random): prevent UniqueID collisions from per-call time seeding (#1860)
UniqueID (and Random/RandomString/RandomInt via newRand) created a fresh *rand.Rand seeded with time.Now().UnixNano() on every call. When invoked in a tight loop or in parallel on machines with coarse timer resolution (e.g. Windows), consecutive calls observe the same timestamp, get the same seed, produce the same sequence, and return identical 'unique' IDs. This leads to duplicate resource names / tfstate keys and flaky parallel tests. TestUniqueID reproduces it reliably on Windows. Use the process-global, auto-seeded (Go 1.20+) and concurrency-safe math/rand source instead. This removes the collision source and also avoids allocating a new generator on every call. No public API changes; output remains non-deterministic as before (the previous code seeded from the wall clock, so it was never deterministic either). Amp-Thread-ID: https://ampcode.com/threads/T-019f32a2-bbac-752b-bbf2-2ee88229b925 Co-authored-by: zuwasi <zuwasi@users.noreply.github.com> Co-authored-by: Amp <amp@ampcode.com>
1 parent deec2c1 commit 9c073bb

1 file changed

Lines changed: 2 additions & 9 deletions

File tree

modules/core/random/random.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ package random
44
import (
55
"bytes"
66
"math/rand"
7-
"time"
87
)
98

109
// Random generates a random int between min and max, inclusive.
1110
func Random(min int, max int) int {
12-
return newRand().Intn(max-min+1) + min
11+
return rand.Intn(max-min+1) + min
1312
}
1413

1514
// RandomInt picks a random element in the slice of ints.
@@ -33,15 +32,9 @@ const uniqueIDLength = 6 // Should be good for 62^6 = 56+ billion combinations
3332
func UniqueID() string {
3433
var out bytes.Buffer
3534

36-
generator := newRand()
3735
for i := 0; i < uniqueIDLength; i++ {
38-
out.WriteByte(base62chars[generator.Intn(len(base62chars))])
36+
out.WriteByte(base62chars[rand.Intn(len(base62chars))])
3937
}
4038

4139
return out.String()
4240
}
43-
44-
// newRand creates a new random number generator, seeding it with the current system time.
45-
func newRand() *rand.Rand {
46-
return rand.New(rand.NewSource(time.Now().UnixNano()))
47-
}

0 commit comments

Comments
 (0)