-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlock_factory.go
71 lines (63 loc) · 1.56 KB
/
lock_factory.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
package dlock
import (
"errors"
"sync"
"github.com/coreos/etcd/clientv3"
)
var (
lockObj *sync.Mutex
lockMap = make(map[string]DistributedLocker)
)
type DistributedLocker interface {
TryGetLock() error
Close()
}
//This is a simple object which holds by the real lock.
//Add more contextual information if needed.
type DistributedLockStub struct {
Owner string
isMaster *int32
msgChan chan string
lease *clientv3.LeaseGrantResponse
}
type DistributedLockOptions struct {
etcdClient *clientv3.Client
Key string
ETCDAddress string
TTL int
//It'll be trigger when get lock.
HoldingLockFunc func()
//It'll be trigger when lost lock.
LosingLockFunc func()
}
func init() {
if lockObj == nil {
lockObj = &sync.Mutex{}
}
}
//Immediately create a new distributed lock instance when there is no any instance with the same Key being created before.
func NewDistributedLock(option DistributedLockOptions) (DistributedLocker, error) {
if option.Key == "" {
return nil, errors.New("option.Key must be set.")
}
if option.HoldingLockFunc == nil {
return nil, errors.New("option.HoldingLockFunc is required for receiving notification.")
}
if option.LosingLockFunc == nil {
return nil, errors.New("option.LosingLockFunc is required for receiving notification.")
}
//set default value.
if option.TTL == 0 {
option.TTL = 5
}
lockObj.Lock()
defer lockObj.Unlock()
var isOK bool
var l DistributedLocker
if l, isOK = lockMap[option.Key]; isOK {
return l, nil
}
l = &distributedLock{options: &option}
lockMap[option.Key] = l
return l, nil
}