582 lines
15 KiB
Go
582 lines
15 KiB
Go
package distributedlock
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"modelRT/distributedlock/constant"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var (
|
|
log *zap.Logger
|
|
rdb *redis.Client
|
|
)
|
|
|
|
func init() {
|
|
log = zap.Must(zap.NewDevelopment())
|
|
rdb = redis.NewClient(&redis.Options{
|
|
Network: "tcp",
|
|
Addr: "192.168.2.104:30001",
|
|
// pool config
|
|
PoolSize: 100, // max connections
|
|
PoolFIFO: true,
|
|
PoolTimeout: 4 * time.Second,
|
|
MinIdleConns: 10, // min idle connections
|
|
MaxIdleConns: 20, // max idle connections
|
|
// tiemout config
|
|
DialTimeout: 5 * time.Second,
|
|
ReadTimeout: 3 * time.Second,
|
|
WriteTimeout: 3 * time.Second,
|
|
})
|
|
}
|
|
|
|
func TestRWLockRLockAndUnRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// 第一次加读锁
|
|
err := rwLocker.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey := strings.Join([]string{rwLocker.rwTokenTimeoutPrefix, rwLocker.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
err = rwLocker.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, redis.Nil, err)
|
|
assert.Equal(t, 0, num)
|
|
t.Log("rwLock rlock and unrlock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLockReentrantRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// 第一次加读锁
|
|
err := rwLocker.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey := strings.Join([]string{rwLocker.rwTokenTimeoutPrefix, rwLocker.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// 第二次加读锁
|
|
err = rwLocker.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 2, num)
|
|
|
|
// 第一次解读锁
|
|
err = rwLocker.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// 第二次解读锁
|
|
err = rwLocker.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, redis.Nil, err)
|
|
assert.Equal(t, 0, num)
|
|
t.Log("rwLock reentrant lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLockRefreshRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 10,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// 第一次加读锁
|
|
err := rwLocker.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey := strings.Join([]string{rwLocker.rwTokenTimeoutPrefix, rwLocker.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
time.Sleep(10 * time.Second)
|
|
script := `return redis.call('httl', KEYS[1], 'fields', '1', ARGV[1]);`
|
|
result, err := rdb.Eval(ctx, script, []string{rwLocker.key}, tokenKey).Result()
|
|
assert.Equal(t, nil, err)
|
|
ttls, ok := result.([]interface{})
|
|
assert.Equal(t, true, ok)
|
|
ttl, ok := ttls[0].(int64)
|
|
assert.Equal(t, true, ok)
|
|
compareValue := int64(8)
|
|
assert.Greater(t, ttl, compareValue)
|
|
|
|
err = rwLocker.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, redis.Nil, err)
|
|
assert.Equal(t, 0, num)
|
|
t.Log("rwLock refresh lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2ClientRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// locker1加读锁
|
|
err := rwLocker1.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2加读锁
|
|
err = rwLocker2.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":")
|
|
num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
err = rdb.HLen(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
hLen := rdb.HLen(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(3), hLen)
|
|
|
|
// locker1解读锁
|
|
err = rwLocker1.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
// locker2解读锁
|
|
err = rwLocker2.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
err = rdb.Exists(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
existNum := rdb.Exists(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(0), existNum)
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2CWith2DifTimeRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 30,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// locker1加读锁
|
|
err := rwLocker1.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2加读锁
|
|
err = rwLocker2.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":")
|
|
num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
err = rdb.HLen(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
hLen := rdb.HLen(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(3), hLen)
|
|
|
|
script := `return redis.call('httl', KEYS[1], 'fields', '1', ARGV[1]);`
|
|
result, err := rdb.Eval(ctx, script, []string{rwLocker1.key}, tokenKey1).Result()
|
|
assert.Equal(t, nil, err)
|
|
ttls, ok := result.([]interface{})
|
|
assert.Equal(t, true, ok)
|
|
ttl, ok := ttls[0].(int64)
|
|
assert.Equal(t, true, ok)
|
|
compareValue := int64(110)
|
|
assert.Greater(t, ttl, compareValue)
|
|
|
|
// locker1解读锁
|
|
err = rwLocker1.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
hashTTL := rdb.TTL(ctx, rwLocker1.key).Val().Seconds()
|
|
assert.Greater(t, hashTTL, float64(20))
|
|
|
|
// locker2解读锁
|
|
err = rwLocker2.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
err = rdb.Exists(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
existNum := rdb.Exists(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(0), existNum)
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2CWithTimeTransformRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 30,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// locker1加读锁
|
|
err := rwLocker1.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2加读锁
|
|
err = rwLocker2.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":")
|
|
num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
err = rdb.HLen(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
hLen := rdb.HLen(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(3), hLen)
|
|
|
|
hashTTL := rdb.TTL(ctx, rwLocker2.key).Val().Seconds()
|
|
assert.Greater(t, hashTTL, float64(100))
|
|
|
|
// locker2解读锁
|
|
err = rwLocker2.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
time.Sleep(10 * time.Second)
|
|
hashTTL = rdb.TTL(ctx, rwLocker1.key).Val().Seconds()
|
|
assert.Greater(t, hashTTL, float64(15))
|
|
|
|
// locker1解读锁
|
|
err = rwLocker1.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
err = rdb.Exists(ctx, rwLocker1.key).Err()
|
|
assert.Equal(t, nil, err)
|
|
existNum := rdb.Exists(ctx, rwLocker1.key).Val()
|
|
assert.Equal(t, int64(0), existNum)
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLockWLockAndUnWLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// 第一次加读锁
|
|
err := rwLocker.WLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey := strings.Join([]string{rwLocker.rwTokenTimeoutPrefix, rwLocker.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
err = rwLocker.UnWLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, redis.Nil, err)
|
|
assert.Equal(t, 0, num)
|
|
t.Log("rwLock rlock and unrlock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLockReentrantWLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// 第一次加写锁
|
|
err := rwLocker.WLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey := strings.Join([]string{rwLocker.rwTokenTimeoutPrefix, rwLocker.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// 第二次加写锁
|
|
err = rwLocker.WLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 2, num)
|
|
|
|
// 第一次解写锁
|
|
err = rwLocker.UnWLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// 第二次解写锁
|
|
err = rwLocker.UnWLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
num, err = rdb.HGet(ctx, rwLocker.key, tokenKey).Int()
|
|
assert.Equal(t, redis.Nil, err)
|
|
assert.Equal(t, 0, num)
|
|
t.Log("rwLock reentrant lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2CWithRLockAndWLockFailed(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 30,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// locker1加读锁
|
|
err := rwLocker1.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2加写锁锁
|
|
duration = 10 * time.Second
|
|
err = rwLocker2.WLock(ctx, duration)
|
|
assert.Equal(t, constant.AcquireTimeoutErr, err)
|
|
|
|
err = rwLocker1.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2CWithRLockAndWLockSucceed(t *testing.T) {
|
|
ctx := context.TODO()
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
duration := 10 * time.Second
|
|
// locker1加读锁
|
|
err := rwLocker1.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
go func() {
|
|
// locker1解写锁
|
|
time.Sleep(10 * time.Second)
|
|
err = rwLocker1.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
}()
|
|
|
|
// locker2加写锁
|
|
duration = 30 * time.Second
|
|
err = rwLocker2.WLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":")
|
|
num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2解写锁
|
|
err = rwLocker2.UnWLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|
|
|
|
func TestRWLock2CWithWLockAndRLock(t *testing.T) {
|
|
ctx := context.TODO()
|
|
|
|
rwLocker1 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 120,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc556a",
|
|
})
|
|
rwLocker1.logger = log
|
|
|
|
rwLocker2 := GetRWLocker(rdb, &RedissionLockConfig{
|
|
LockLeaseTime: 30,
|
|
NeedRefresh: true,
|
|
Key: "component",
|
|
Token: "fd348a84-e07c-4a61-8c19-f753e6bc5577",
|
|
})
|
|
rwLocker2.logger = log
|
|
|
|
duration := 10 * time.Second
|
|
// locker1加写锁
|
|
err := rwLocker1.WLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey1 := strings.Join([]string{rwLocker1.rwTokenTimeoutPrefix, rwLocker1.token}, ":")
|
|
num, err := rdb.HGet(ctx, rwLocker1.key, tokenKey1).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
go func() {
|
|
// locker1解写锁
|
|
time.Sleep(10 * time.Second)
|
|
err = rwLocker1.UnWLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
}()
|
|
|
|
// locker2加读锁
|
|
duration = 30 * time.Second
|
|
err = rwLocker2.RLock(ctx, duration)
|
|
assert.Equal(t, nil, err)
|
|
|
|
tokenKey2 := strings.Join([]string{rwLocker2.rwTokenTimeoutPrefix, rwLocker2.token}, ":")
|
|
num, err = rdb.HGet(ctx, rwLocker2.key, tokenKey2).Int()
|
|
assert.Equal(t, nil, err)
|
|
assert.Equal(t, 1, num)
|
|
|
|
// locker2解读锁
|
|
err = rwLocker2.UnRLock(ctx)
|
|
assert.Equal(t, nil, err)
|
|
|
|
t.Log("rwLock 2 client lock test success")
|
|
return
|
|
}
|