forked from aputs/kube-register
-
Notifications
You must be signed in to change notification settings - Fork 0
/
role.go
83 lines (72 loc) · 2.08 KB
/
role.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
package registry
import (
"path"
"time"
"github.com/coreos/fleet/etcd"
)
const (
leasePrefix = "lease"
)
// LeaseRole acquires a lease of a role only if there are no outstanding
// leases. If a Lease cannot be acquired, a nil Lease object is returned.
// An error is returned only if there is a failure communicating with the Registry.
func (r *EtcdRegistry) LeaseRole(role, machID string, period time.Duration) (Lease, error) {
key := path.Join(r.keyPrefix, leasePrefix, role)
req := etcd.Create{
Key: key,
Value: machID,
TTL: period,
}
var lease Lease
resp, err := r.etcd.Do(&req)
if err == nil {
lease = &etcdRoleLease{
key: key,
value: machID,
idx: resp.Node.ModifiedIndex,
etcd: r.etcd,
}
} else if isNodeExist(err) {
err = nil
}
return lease, err
}
// etcdRoleLease is a proxy to an auto-expiring lease stored in the Registry.
// The creator of a Lease must repeatedly call Renew to keep their lease from
// expiring. etcdRoleLease implements the Lease interface.
type etcdRoleLease struct {
key string
value string
idx uint64
etcd etcd.Client
}
// Release explicitly releases the ownership of a lease back to the Registry.
// After calling Release, the etcdRoleLease object should be discarded. An
// error is returned if the etcdRoleLease has already expired, or if
// communication with the Registry fails.
func (l *etcdRoleLease) Release() error {
req := etcd.Delete{
Key: l.key,
PreviousIndex: l.idx,
}
_, err := l.etcd.Do(&req)
return err
}
// Renew attempts to update the remaining lease time to the provided time
// period. It will only succeed if the lease has not been changed in the
// Registry since it was last renewed or first acquired.
// An error is returned if the lease has already expired, or if communication
// with the Registry fails.
func (l *etcdRoleLease) Renew(period time.Duration) error {
req := etcd.Set{
Key: l.key,
Value: l.value,
PreviousIndex: l.idx,
TTL: period,
}
resp, err := l.etcd.Do(&req)
if err == nil {
l.idx = resp.Node.ModifiedIndex
}
return err
}