diff --git a/registry/consul_registry.go b/registry/consul_registry.go index 6b45d11283..af5d0adff8 100644 --- a/registry/consul_registry.go +++ b/registry/consul_registry.go @@ -24,6 +24,8 @@ type consulRegistry struct { sync.Mutex register map[string]uint64 + // lastChecked tracks when a node was last checked as existing in Consul + lastChecked map[string]time.Time } func getDeregisterTTL(t time.Duration) time.Duration { @@ -118,8 +120,9 @@ func configure(c *consulRegistry, opts ...Option) { func newConsulRegistry(opts ...Option) Registry { cr := &consulRegistry{ - opts: Options{}, - register: make(map[string]uint64), + opts: Options{}, + register: make(map[string]uint64), + lastChecked: make(map[string]time.Time), } configure(cr, opts...) return cr @@ -135,9 +138,10 @@ func (c *consulRegistry) Deregister(s *Service) error { return errors.New("Require at least one node") } - // delete our hash of the service + // delete our hash and time check of the service c.Lock() delete(c.register, s.Name) + delete(c.lastChecked, s.Name) c.Unlock() node := s.Nodes[0] @@ -181,7 +185,13 @@ func (c *consulRegistry) Register(s *Service, opts ...RegisterOption) error { // if it's already registered and matches then just pass the check if ok && v == h { if options.TTL == time.Duration(0) { - services, _, err := c.Client.Health().Checks(s.Name, nil) + // ensure that our service hasn't been deregistered by Consul + if time.Since(c.lastChecked[s.Name]) <= getDeregisterTTL(regInterval) { + return nil + } + services, _, err := c.Client.Health().Checks(s.Name, &consul.QueryOptions{ + AllowStale: true, + }) if err == nil { for _, v := range services { if v.ServiceID == node.Id { @@ -245,9 +255,10 @@ func (c *consulRegistry) Register(s *Service, opts ...RegisterOption) error { return err } - // save our hash of the service + // save our hash and time check of the service c.Lock() c.register[s.Name] = h + c.lastChecked[s.Name] = time.Now() c.Unlock() // if the TTL is 0 we don't mess with the checks