8 | 8 |
"github.com/go-kit/kit/log"
|
9 | 9 |
)
|
10 | 10 |
|
11 | |
const (
|
12 | |
minHeartBeatTime = time.Millisecond * 500
|
13 | |
)
|
|
11 |
const minHeartBeatTime = 500 * time.Millisecond
|
14 | 12 |
|
15 | 13 |
// Registrar registers service instance liveness information to etcd.
|
16 | 14 |
type Registrar struct {
|
17 | 15 |
client Client
|
18 | 16 |
service Service
|
19 | 17 |
logger log.Logger
|
|
18 |
|
|
19 |
quitmtx sync.Mutex
|
20 | 20 |
quit chan struct{}
|
21 | |
sync.Mutex
|
22 | 21 |
}
|
23 | 22 |
|
24 | 23 |
// Service holds the instance identifying data you want to publish to etcd. Key
|
|
38 | 37 |
ttl time.Duration // e.g. time.Second * 10
|
39 | 38 |
}
|
40 | 39 |
|
41 | |
// NewTTLOption returns a TTLOption that contains proper ttl settings. param
|
42 | |
// heartbeat is used to refresh lease of the key periodically by a loop goroutine,
|
43 | |
// its value should be at least 500ms. param ttl definite the lease of the key,
|
44 | |
// its value should be greater than heartbeat's.
|
45 | |
// e.g. heartbeat: time.Second * 3, ttl: time.Second * 10.
|
|
40 |
// NewTTLOption returns a TTLOption that contains proper TTL settings. Heartbeat
|
|
41 |
// is used to refresh the lease of the key periodically; its value should be at
|
|
42 |
// least 500ms. TTL defines the lease of the key; its value should be
|
|
43 |
// significantly greater than heartbeat.
|
|
44 |
//
|
|
45 |
// Good default values might be 3s heartbeat, 10s TTL.
|
46 | 46 |
func NewTTLOption(heartbeat, ttl time.Duration) *TTLOption {
|
47 | 47 |
if heartbeat <= minHeartBeatTime {
|
48 | 48 |
heartbeat = minHeartBeatTime
|
49 | 49 |
}
|
50 | 50 |
if ttl <= heartbeat {
|
51 | |
ttl = heartbeat * 3
|
|
51 |
ttl = 3 * heartbeat
|
52 | 52 |
}
|
53 | 53 |
return &TTLOption{
|
54 | 54 |
heartbeat: heartbeat,
|
|
83 | 83 |
}
|
84 | 84 |
|
85 | 85 |
func (r *Registrar) loop() {
|
86 | |
r.Lock()
|
|
86 |
r.quitmtx.Lock()
|
|
87 |
if r.quit != nil {
|
|
88 |
return // already running
|
|
89 |
}
|
87 | 90 |
r.quit = make(chan struct{})
|
88 | |
r.Unlock()
|
|
91 |
r.quitmtx.Unlock()
|
89 | 92 |
|
90 | 93 |
tick := time.NewTicker(r.service.TTL.heartbeat)
|
91 | 94 |
defer tick.Stop()
|
92 | |
|
93 | 95 |
for {
|
94 | 96 |
select {
|
95 | |
case <-r.quit:
|
96 | |
return
|
97 | 97 |
case <-tick.C:
|
98 | 98 |
if err := r.client.Register(r.service); err != nil {
|
99 | 99 |
r.logger.Log("err", err)
|
100 | 100 |
}
|
|
101 |
case <-r.quit:
|
|
102 |
return
|
101 | 103 |
}
|
102 | 104 |
}
|
103 | 105 |
}
|
|
110 | 112 |
} else {
|
111 | 113 |
r.logger.Log("action", "deregister")
|
112 | 114 |
}
|
113 | |
r.Lock()
|
114 | |
defer r.Unlock()
|
|
115 |
|
|
116 |
r.quitmtx.Lock()
|
|
117 |
defer r.quitmtx.Unlock()
|
115 | 118 |
if r.quit != nil {
|
116 | 119 |
close(r.quit)
|
117 | 120 |
r.quit = nil
|