forked from RichardKnop/machinery
/
eager.go
57 lines (50 loc) · 943 Bytes
/
eager.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
package eager
import (
"errors"
"sync"
"time"
)
var (
ErrEagerLockFailed = errors.New("eager lock: failed to acquire lock")
)
type Lock struct {
retries int
interval time.Duration
register struct {
sync.RWMutex
m map[string]int64
}
}
func New() *Lock {
return &Lock{
retries: 3,
interval: 5 * time.Second,
register: struct {
sync.RWMutex
m map[string]int64
}{
m: make(map[string]int64),
},
}
}
func (e *Lock) LockWithRetries(key string, value int64) error {
for i := 0; i <= e.retries; i++ {
err := e.Lock(key, value)
if err == nil {
//成功拿到锁,返回
return nil
}
time.Sleep(e.interval)
}
return ErrEagerLockFailed
}
func (e *Lock) Lock(key string, value int64) error {
e.register.Lock()
defer e.register.Unlock()
timeout, exist := e.register.m[key]
if !exist || time.Now().UnixNano() > timeout {
e.register.m[key] = value
return nil
}
return ErrEagerLockFailed
}