go-redis
go-redis copied to clipboard
fix: race slice for list function of ring client
summary
s1 := s0
is shallow copy. when concurrently process read and write (append) operator for slice, raise data race. so, use copy()
to deep copy slice object.
test
ut
func TestRaceSlice(t *testing.T) {
var a1 = make([]string, 3)
var b1 = []string{"a", "b", "c"}
// race error
a1 = b1
// race ok
// copy(a1, b1)
fmt.Printf("a1 >%v", (*reflect.SliceHeader)(unsafe.Pointer(&a1)))
fmt.Println()
fmt.Printf("b1 >%v", (*reflect.SliceHeader)(unsafe.Pointer(&b1)))
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10000; i++ {
a1[0] = "aa"
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10000; i++ {
b1[0] = "bb"
}
}()
wg.Wait()
}
test result
=== RUN TestRaceSlice
a1 >&{824636064176 3 3}
b1 >&{824636064176 3 3}==================
WARNING: DATA RACE
Write at 0x00c00023c1b0 by goroutine 8:
github.com/redis/go-redis/v9_test.TestRaceSlice.func1()
/Users/ruifengyun/github/rfyiamcool/go-redis/main_test.go:504 +0xcf
Previous write at 0x00c00023c1b0 by goroutine 9:
github.com/redis/go-redis/v9_test.TestRaceSlice.func2()
/Users/ruifengyun/github/rfyiamcool/go-redis/main_test.go:512 +0xcf
Goroutine 8 (running) created at:
github.com/redis/go-redis/v9_test.TestRaceSlice()
/Users/ruifengyun/github/rfyiamcool/go-redis/main_test.go:501 +0x427
testing.tRunner()
/usr/local/go/src/testing/testing.go:1595 +0x238
testing.(*T).Run.func1()
/usr/local/go/src/testing/testing.go:1648 +0x44
Goroutine 9 (running) created at:
github.com/redis/go-redis/v9_test.TestRaceSlice()
/Users/ruifengyun/github/rfyiamcool/go-redis/main_test.go:509 +0x4e4
testing.tRunner()
/usr/local/go/src/testing/testing.go:1595 +0x238
testing.(*T).Run.func1()
/usr/local/go/src/testing/testing.go:1648 +0x44
==================
testing.go:1465: race detected during execution of test
--- FAIL: TestRaceSlice (0.00s)
=== NAME
testing.go:1465: race detected during execution of test
FAIL
FAIL github.com/redis/go-redis/v9 0.384s
FAIL