-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredisLock.go
88 lines (79 loc) · 1.89 KB
/
redisLock.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package redis
import (
"github.com/farseer-go/fs"
"github.com/farseer-go/fs/core"
"github.com/farseer-go/fs/flog"
"github.com/farseer-go/fs/stopwatch"
"github.com/go-redis/redis/v8"
"time"
)
// 分布式锁
type redisLock struct {
rdb *redis.Client
}
type lockResult struct {
key string // 锁名称
val string // 锁值
expiration time.Duration
rdb *redis.Client
}
// LockNew 创建锁
func (r redisLock) LockNew(key, val string, expiration time.Duration) core.ILock {
return &lockResult{
rdb: r.rdb,
key: key,
val: val,
expiration: expiration,
}
}
// TryLock 尝试加锁
func (r *lockResult) TryLock() bool {
cmd := r.rdb.SetNX(fs.Context, r.key, r.val, r.expiration)
result, err := cmd.Result()
if err != nil {
_ = flog.Errorf("redis加锁异常:%s", err.Error())
}
return result
}
// TryLockRun 尝试加锁,执行完后,自动释放锁
func (r *lockResult) TryLockRun(fn func()) bool {
sw := stopwatch.StartNew()
cmd := r.rdb.SetNX(fs.Context, r.key, r.val, r.expiration)
result, err := cmd.Result()
flog.Debugf("获取Redis锁,耗时:%s", sw.GetMicrosecondsText())
if err != nil {
_ = flog.Errorf("redis加锁异常:%s", err.Error())
}
if result {
defer r.ReleaseLock()
fn()
}
return result
}
// GetLock 获取锁,直到获取成功
func (r *lockResult) GetLock() {
for {
cmd := r.rdb.SetNX(fs.Context, r.key, r.val, r.expiration)
result, err := cmd.Result()
if err != nil {
_ = flog.Errorf("redis加锁异常:%s", err.Error())
}
if result {
return
}
time.Sleep(100 * time.Millisecond)
}
}
// GetLockRun 获取锁,直到获取成功,执行完后,自动释放锁
func (r *lockResult) GetLockRun(fn func()) {
for {
if r.TryLockRun(fn) {
return
}
time.Sleep(100 * time.Millisecond)
}
}
// ReleaseLock 锁放锁
func (r *lockResult) ReleaseLock() {
r.rdb.Del(fs.Context, r.key)
}