package redislock_test
import (
"context"
"sync"
"testing"
"time"
"github.com/TDroyal/redislock"
)
func TestNonBlockLock(t *testing.T) {
// node1
c1 := redislock.NewClient("tcp", "xxxxxx:xxxx", "yyyyyy", redislock.WithMaxActive(20), redislock.WithIdleTimeoutSeconds(10))
var locker1 redislock.RedisLock = redislock.NewRedisDistributedLock("non_block_test_key", c1, redislock.WithExpireSeconds(3))
// node2
c2 := redislock.NewClient("tcp", "xxxxxx:xxxx", "yyyyyy", redislock.WithMaxActive(20), redislock.WithIdleTimeoutSeconds(10))
var locker2 redislock.RedisLock = redislock.NewRedisDistributedLock("non_block_test_key", c2, redislock.WithExpireSeconds(3))
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
err := locker1.Lock(context.Background())
// if err == nil {
// locker1.UnLock(context.Background())
// }
t.Log(err) // <nil>
}()
go func() {
time.Sleep(time.Millisecond)
defer wg.Done()
err := locker2.Lock(context.Background())
if err == nil {
locker2.UnLock(context.Background())
}
t.Log(err) // lock is acquired by others
}()
wg.Wait()
}
func TestBlockLock(t *testing.T) {
// node1
c1 := redislock.NewClient("tcp", "xxxxxx:xxxx", "yyyyyy", redislock.WithMaxActive(20), redislock.WithIdleTimeoutSeconds(10))
locker1 := redislock.NewRedisDistributedLock("block_test_key", c1, redislock.WithExpireSeconds(3))
// node2
c2 := redislock.NewClient("tcp", "xxxxxx:xxxx", "yyyyyy", redislock.WithMaxActive(20), redislock.WithIdleTimeoutSeconds(10))
locker2 := redislock.NewRedisDistributedLock("block_test_key", c2, redislock.WithBlock(), redislock.WithBlockingSeconds(5), redislock.WithWatchDogMode(), redislock.WithExpireSeconds(15))
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
err := locker1.Lock(context.Background())
// if err == nil {
// locker1.UnLock(context.Background())
// }
t.Logf("time: %v, error: %v", time.Now().Format("2006-01-02 15:04:05"), err) // time: 2026-05-21 15:22:24, error: <nil>
}()
go func() {
time.Sleep(time.Millisecond * 10)
defer wg.Done()
err := locker2.Lock(context.Background())
if err == nil {
locker2.UnLock(context.Background())
}
t.Logf("time: %v, error: %v", time.Now().Format("2006-01-02 15:04:05"), err) // time: 2026-05-21 15:22:27, error: <nil>
}()
wg.Wait()
}
func TestRedLock(t *testing.T) {
confs := []*redislock.SingleRedisNodeConf{
{
Network: "tcp",
Address: "xxxxxx:xxxx",
Password: "yyyyyy",
RedisOpts: []redislock.RedisOption{
redislock.WithMaxActive(20),
redislock.WithIdleTimeoutSeconds(10),
},
},
{
Network: "tcp",
Address: "xxxxxx:xxxx",
Password: "yyyyyy",
RedisOpts: []redislock.RedisOption{
redislock.WithMaxActive(20),
redislock.WithIdleTimeoutSeconds(10),
},
},
{
Network: "tcp",
Address: "xxxxxx:xxxx",
Password: "yyyyyy",
RedisOpts: []redislock.RedisOption{
redislock.WithMaxActive(20),
redislock.WithIdleTimeoutSeconds(10),
},
},
}
// node1
// locker1 := redislock.NewRedLock("red_lock", confs, redislock.WithBlock(), redislock.WithBlockingSeconds(5), redislock.WithWatchDogMode(), redislock.WithExpireSeconds(15))
locker1 := redislock.NewRedLock("red_lock", confs, redislock.WithExpireSeconds(3))
// node2
locker2 := redislock.NewRedLock("red_lock", confs, redislock.WithExpireSeconds(3))
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
err := locker1.Lock(context.Background())
t.Log(err) // <nil>
}()
go func() {
time.Sleep(time.Millisecond)
defer wg.Done()
err := locker2.Lock(context.Background())
if err == nil {
locker2.UnLock(context.Background())
}
t.Log(err) // lock failed
}()
wg.Wait()
}