1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-22 12:13:36 +00:00

Merge pull request #786 from ReneWerner87/UUID_thread_safe

 Make UUID function thread-safe
This commit is contained in:
Fenny 2020-09-15 16:41:53 +02:00 committed by GitHub
commit 1cfca9bac6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 2 deletions

View File

@ -10,6 +10,7 @@ import (
"encoding/hex"
"reflect"
"runtime"
"sync"
"sync/atomic"
)
@ -22,14 +23,18 @@ const toUpperTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11
var uuidSeed [24]byte
var uuidCounter uint64
var uuidSetup sync.Once
func UUID() string {
// Setup seed & counter once
if uuidCounter <= 0 {
uuidSetup.Do(func() {
if _, err := rand.Read(uuidSeed[:]); err != nil {
return "00000000-0000-0000-0000-000000000000"
return
}
uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])
})
if atomic.LoadUint64(&uuidCounter) <= 0 {
return "00000000-0000-0000-0000-000000000000"
}
// first 8 bytes differ, taking a slice of the first 16 bytes
x := atomic.AddUint64(&uuidCounter, 1)

View File

@ -24,6 +24,25 @@ func Test_Utils_UUID(t *testing.T) {
t.Parallel()
res := UUID()
AssertEqual(t, 36, len(res))
AssertEqual(t, true, res != "00000000-0000-0000-0000-000000000000")
}
func Test_Utils_UUID_Concurrency(t *testing.T) {
t.Parallel()
iterations := 10000
var res string
ch := make(chan string, iterations)
results := make(map[string]string)
for i := 0; i < iterations; i++ {
go func() {
ch <- UUID()
}()
}
for i := 0; i < iterations; i++ {
res = <-ch
results[res] = res
}
AssertEqual(t, iterations, len(results))
}
// go test -v -run=^$ -bench=Benchmark_UUID -benchmem -count=2