mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Util: Fix panic when generating UIDs concurrently (#69476)
This commit is contained in:
parent
1ed4c0382b
commit
fe2103bfc8
@ -3,6 +3,7 @@ package util
|
|||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -12,6 +13,11 @@ var uidrand = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|||||||
var alphaRunes = []rune("abcdefghijklmnopqrstuvwxyz")
|
var alphaRunes = []rune("abcdefghijklmnopqrstuvwxyz")
|
||||||
var hexLetters = []rune("abcdef")
|
var hexLetters = []rune("abcdef")
|
||||||
|
|
||||||
|
// We want to protect our number generator as they are not thread safe. Not using
|
||||||
|
// the mutex could result in panics in certain cases where UIDs would be generated
|
||||||
|
// at the same time.
|
||||||
|
var mtx sync.Mutex
|
||||||
|
|
||||||
// Legacy UID pattern
|
// Legacy UID pattern
|
||||||
var validUIDPattern = regexp.MustCompile(`^[a-zA-Z0-9\-\_]*$`).MatchString
|
var validUIDPattern = regexp.MustCompile(`^[a-zA-Z0-9\-\_]*$`).MatchString
|
||||||
|
|
||||||
@ -30,6 +36,8 @@ func IsShortUIDTooLong(uid string) bool {
|
|||||||
// it is guaranteed to have a character as the first letter
|
// it is guaranteed to have a character as the first letter
|
||||||
// This UID will be a valid k8s name
|
// This UID will be a valid k8s name
|
||||||
func GenerateShortUID() string {
|
func GenerateShortUID() string {
|
||||||
|
mtx.Lock()
|
||||||
|
defer mtx.Unlock()
|
||||||
uid, err := uuid.NewRandom()
|
uid, err := uuid.NewRandom()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This should never happen... but this seems better than a panic
|
// This should never happen... but this seems better than a panic
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -16,6 +17,25 @@ func TestAllowedCharMatchesUidPattern(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run with "go test -race -run ^TestThreadSafe$ github.com/grafana/grafana/pkg/util"
|
||||||
|
func TestThreadSafe(t *testing.T) {
|
||||||
|
// This test was used to showcase the bug, unfortunately there is
|
||||||
|
// no way to enable the -race flag programmatically.
|
||||||
|
t.Skip()
|
||||||
|
// Use 1000 go routines to create 100 UIDs each at roughly the same time.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
go func() {
|
||||||
|
for ii := 0; ii < 100; ii++ {
|
||||||
|
_ = GenerateShortUID()
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
wg.Add(1)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestRandomUIDs(t *testing.T) {
|
func TestRandomUIDs(t *testing.T) {
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
v := GenerateShortUID()
|
v := GenerateShortUID()
|
||||||
|
Loading…
Reference in New Issue
Block a user