Closed maxid closed 6 months ago
Can you please show runnable code that demonstrates the problem? Thanks.
Can you please show runnable code that demonstrates the problem? Thanks.
package main
import (
"context"
"fmt"
"time"
"unsafe"
"github.com/buraksezer/olric"
"github.com/buraksezer/olric/config"
"github.com/cespare/xxhash/v2"
)
type xxhasher struct {
}
func (xh xxhasher) Sum64(key []byte) uint64 {
fmt.Println(fmt.Sprintf("key %s, length: %d", string(key), len(key)))
return xxhash.Sum64(key) // replace to xxhash.Sum64([]byte(string(key))) can fixed this problem
}
var _dm olric.DMap
func main() {
// in this case key length >= 32 always test pass
tmp := "test-cluster-dmap" + "lock.xxx-xxxxx-xxxx-xxx"
fmt.Println(fmt.Sprintf("key length: %d", len(tmp)))
fmt.Println(xxhash.Sum64(*(*[]byte)(unsafe.Pointer(&tmp))))
// but this case some time test failure
initOlric()
testDLock("xxx-xxxxx") // key length < 32, test pass
testDLock("xxx-xxxxx-xxxx-xxx") // key length >= 32, test failure
}
func initOlric() {
ctx, cancel := context.WithCancel(context.Background())
var db *olric.Olric
c := config.New("local")
c.Hasher = xxhasher{}
c.Started = func() {
defer cancel()
fmt.Println("olric cluster is ready to accept connections")
}
db, err := olric.New(c)
if err != nil {
fmt.Println(fmt.Sprintf("Failed to create olric cluster instance: %v", err))
}
go func() {
err = db.Start()
if err != nil {
fmt.Println(fmt.Sprintf("olric cluster Start returned an error: %v", err))
}
}()
<-ctx.Done()
if db != nil {
embeddedClient := db.NewEmbeddedClient()
if dm, err := embeddedClient.NewDMap(fmt.Sprintf("%s-cluster-dmap", "test")); err == nil {
_dm = dm
}
}
}
func testDLock(key string) {
if _dm != nil {
ctx := context.Background()
if lock, err := _dm.Lock(ctx, fmt.Sprintf("lock.%s", key), time.Second*5); err == nil {
_ = lock.Unlock(ctx) // <--- failure
}
}
}
2024/03/19 10:26:10 [INFO] Routing table has been pushed by 127.0.0.1:3320 => operations.go:86
2024/03/19 10:26:10 [INFO] The cluster coordinator has been bootstrapped => discovery.go:42
2024/03/19 10:26:10 [INFO] Memberlist bindAddr: 127.0.0.1, bindPort: 3322 => routingtable.go:413
2024/03/19 10:26:10 [INFO] Cluster coordinator: 127.0.0.1:3320 => routingtable.go:414
2024/03/19 10:26:10 [INFO] Node name in the cluster: 127.0.0.1:3320 => olric.go:380
2024/03/19 10:26:10 [INFO] Olric bindAddr: 127.0.0.1, bindPort: 3320 => olric.go:386
2024/03/19 10:26:10 [INFO] Replication count is 1 => olric.go:388
olric cluster is ready to accept connections
key test-cluster-dmaplock.xxx-xxxxx, length: 31
key test-cluster-dmaplock.xxx-xxxxx, length: 31
key test-cluster-dmaplock.xxx-xxxxx, length: 31
key test-cluster-dmaplock.xxx-xxxxx, length: 31
key test-cluster-dmaplock.xxx-xxxxx, length: 31
key test-cluster-dmaplock.xxx-xxxxx-xxxx-xxx, length: 40
panic: runtime error: slice bounds out of range [::40] with capacity 0
goroutine 1 [running]:
github.com/cespare/xxhash/v2.Sum64({0x140000ce2d0, 0x28, 0x0})
.../vendor/github.com/cespare/xxhash/v2/xxhash_other.go:22 +0x6c4
main.xxhasher.Sum64({}, {0x140000ce2d0, 0x28, 0x0})
.../main.go:19 +0x1b8
github.com/buraksezer/olric/internal/cluster/partitions.HKey({0x140004ea000, 0x11}, {0x140004ea030, 0x17})
.../vendor/github.com/buraksezer/olric/internal/cluster/partitions/hkey.go:37 +0x8c
github.com/buraksezer/olric/internal/dmap.(*DMap).put(0x140004ec000, 0x140004f0100)
.../vendor/github.com/buraksezer/olric/internal/dmap/put.go:363 +0x68
github.com/buraksezer/olric/internal/dmap.(*DMap).tryLock(0x140004ec000, 0x140004f0100, 0x12a05f200)
.../vendor/github.com/buraksezer/olric/internal/dmap/lock.go:94 +0x3c
github.com/buraksezer/olric/internal/dmap.(*DMap).Lock(0x140004ec000, {0x104ff5b10, 0x10544ce20}, {0x140004ea030, 0x17}, 0x0, 0x12a05f200)
.../vendor/github.com/buraksezer/olric/internal/dmap/lock.go:157 +0x264
github.com/buraksezer/olric.(*EmbeddedDMap).Lock(0x14000126000, {0x104ff5b10, 0x10544ce20}, {0x140004ea030, 0x17}, 0x12a05f200)
.../vendor/github.com/buraksezer/olric/embedded_client.go:167 +0x78
main.testDLock({0x104e27713, 0x12})
.../main.go:70 +0x11c
main.main()
.../main.go:33 +0x210
Exiting.
Debugger finished with the exit code 0
Can you make a simpler reproducer without the other packages? I suspect there is a bug in your code. At a glance, my best guess is that you have a data race on the slice you're passing to Sum64
(you can run with -race
to check). But I'd want a simpler repro case before I do more debugging.
Can you make a simpler reproducer without the other packages? I suspect there is a bug in your code. At a glance, my best guess is that you have a data race on the slice you're passing to
Sum64
(you can run with-race
to check). But I'd want a simpler repro case before I do more debugging.
You are right!Thanks!
// xxhash.go:211 maybe binary.LittleEndian.Uint64(b) have a data race ?
func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }
panic: runtime error: slice bounds out of range [::41] with capacity 9
goroutine 1 [running]: github.com/cespare/xxhash/v2.Sum64({0x14014c9ecc0, 0x29, 0x9}) .../vendor/github.com/cespare/xxhash/v2/xxhash_other.go:22 +0x6c4