3 | 3 |
etcd "github.com/coreos/etcd/client"
|
4 | 4 |
|
5 | 5 |
"github.com/go-kit/kit/log"
|
|
6 |
"time"
|
|
7 |
)
|
|
8 |
|
|
9 |
const (
|
|
10 |
MinHeartBeatTime = time.Millisecond * 500
|
6 | 11 |
)
|
7 | 12 |
|
8 | 13 |
// Registrar registers service instance liveness information to etcd.
|
|
10 | 15 |
client Client
|
11 | 16 |
service Service
|
12 | 17 |
logger log.Logger
|
|
18 |
quit chan struct{}
|
13 | 19 |
}
|
14 | 20 |
|
15 | 21 |
// Service holds the instance identifying data you want to publish to etcd. Key
|
|
18 | 24 |
type Service struct {
|
19 | 25 |
Key string // unique key, e.g. "/service/foobar/1.2.3.4:8080"
|
20 | 26 |
Value string // returned to subscribers, e.g. "http://1.2.3.4:8080"
|
|
27 |
TTL *TTLOption
|
21 | 28 |
DeleteOptions *etcd.DeleteOptions
|
|
29 |
}
|
|
30 |
|
|
31 |
// TTLOption allow setting a key with a TTL, and regularly refreshes the lease with a goroutine
|
|
32 |
type TTLOption struct {
|
|
33 |
Heartbeat time.Duration
|
|
34 |
TTL time.Duration
|
|
35 |
}
|
|
36 |
|
|
37 |
// NewTTLOption returns a TTLOption
|
|
38 |
func NewTTLOption(heartbeat, ttl time.Duration) *TTLOption {
|
|
39 |
if heartbeat <= MinHeartBeatTime {
|
|
40 |
heartbeat = MinHeartBeatTime
|
|
41 |
}
|
|
42 |
if ttl <= heartbeat {
|
|
43 |
ttl = heartbeat * 3
|
|
44 |
}
|
|
45 |
return &TTLOption{heartbeat, ttl}
|
22 | 46 |
}
|
23 | 47 |
|
24 | 48 |
// NewRegistrar returns a etcd Registrar acting on the provided catalog
|
|
42 | 66 |
} else {
|
43 | 67 |
r.logger.Log("action", "register")
|
44 | 68 |
}
|
|
69 |
if r.service.TTL == nil {
|
|
70 |
return
|
|
71 |
}
|
|
72 |
r.quit = make(chan struct{})
|
|
73 |
go func() {
|
|
74 |
for {
|
|
75 |
select {
|
|
76 |
case <-r.quit:
|
|
77 |
return
|
|
78 |
case <-time.After(r.service.TTL.Heartbeat):
|
|
79 |
if err := r.client.Register(r.service); err != nil {
|
|
80 |
r.logger.Log("err", err)
|
|
81 |
}
|
|
82 |
}
|
|
83 |
}
|
|
84 |
}()
|
45 | 85 |
}
|
46 | 86 |
|
47 | 87 |
// Deregister implements the sd.Registrar interface. Call it when you want your
|
|
52 | 92 |
} else {
|
53 | 93 |
r.logger.Log("action", "deregister")
|
54 | 94 |
}
|
|
95 |
if r.quit != nil {
|
|
96 |
close(r.quit)
|
|
97 |
}
|
55 | 98 |
}
|