8 "github.com/go-kit/kit/log"
9 "github.com/go-kit/kit/sd"
10 "github.com/go-kit/kit/sd/internal/instance"
13 // Instancer yields instances from the named DNS SRV record. The name is
14 // resolved on a fixed schedule. Priorities and weights are ignored.
15 type Instancer struct {
22 // NewInstancer returns a DNS SRV instancer.
28 return NewInstancerDetailed(name, time.NewTicker(ttl), net.LookupSRV, logger)
31 // NewInstancerDetailed is the same as NewInstancer, but allows users to
32 // provide an explicit lookup refresh ticker instead of a TTL, and specify the
33 // lookup function instead of using net.LookupSRV.
34 func NewInstancerDetailed(
41 cache: instance.NewCache(),
44 quit: make(chan struct{}),
47 instances, err := p.resolve(lookup)
49 logger.Log("name", name, "instances", len(instances))
51 logger.Log("name", name, "err", err)
53 p.cache.Update(sd.Event{Instances: instances, Err: err})
55 go p.loop(refresh, lookup)
59 // Stop terminates the Instancer.
60 func (p *Instancer) Stop() {
64 func (p *Instancer) loop(t *time.Ticker, lookup Lookup) {
69 instances, err := p.resolve(lookup)
71 p.logger.Log("name", p.name, "err", err)
72 p.cache.Update(sd.Event{Err: err})
73 continue // don't replace potentially-good with bad
75 p.cache.Update(sd.Event{Instances: instances})
83 func (p *Instancer) resolve(lookup Lookup) ([]string, error) {
84 _, addrs, err := lookup("", "", p.name)
88 instances := make([]string, len(addrs))
89 for i, addr := range addrs {
90 instances[i] = net.JoinHostPort(addr.Target, fmt.Sprint(addr.Port))
95 // Register implements Instancer.
96 func (s *Instancer) Register(ch chan<- sd.Event) {
100 // Deregister implements Instancer.
101 func (s *Instancer) Deregister(ch chan<- sd.Event) {
102 s.cache.Deregister(ch)