diff --git a/registry/consul/options.go b/registry/consul/options.go index aefce92a..3feb9cef 100644 --- a/registry/consul/options.go +++ b/registry/consul/options.go @@ -2,6 +2,7 @@ package consul import ( "context" + "time" consul "github.com/hashicorp/consul/api" "github.com/micro/go-micro/registry" @@ -15,3 +16,22 @@ func Config(c *consul.Config) registry.Option { o.Context = context.WithValue(o.Context, "consul_config", c) } } + +// +// TCPCheck will tell the service provider to check the service address +// and port every `t` interval. It will enabled only if `t` is greater than 0. +// See `TCP + Interval` for more information [1]. +// +// [1] https://www.consul.io/docs/agent/checks.html +// +func TCPCheck(t time.Duration) registry.Option { + return func(o *registry.Options) { + if t <= time.Duration(0) { + return + } + if o.Context == nil { + o.Context = context.Background() + } + o.Context = context.WithValue(o.Context, "consul_tcp_check", t) + } +} diff --git a/registry/consul_registry.go b/registry/consul_registry.go index a3387dba..a58da58e 100644 --- a/registry/consul_registry.go +++ b/registry/consul_registry.go @@ -115,16 +115,39 @@ func (c *consulRegistry) Deregister(s *Service) error { return c.Client.Agent().ServiceDeregister(node.Id) } +func getDeregisterTTL(t time.Duration) time.Duration { + // splay slightly for the watcher? + splay := time.Second * 5 + deregTTL := t + splay + + // consul has a minimum timeout on deregistration of 1 minute. + if t < time.Minute { + deregTTL = time.Minute + splay + } + + return deregTTL +} + func (c *consulRegistry) Register(s *Service, opts ...RegisterOption) error { if len(s.Nodes) == 0 { return errors.New("Require at least one node") } + var regTCPCheck bool + var regInterval time.Duration + var options RegisterOptions for _, o := range opts { o(&options) } + if c.opts.Context != nil { + if tcpCheckInterval, ok := c.opts.Context.Value("consul_tcp_check").(time.Duration); ok { + regTCPCheck = true + regInterval = tcpCheckInterval + } + } + // create hash of service; uint64 h, err := hash.Hash(s, nil) if err != nil { @@ -155,16 +178,19 @@ func (c *consulRegistry) Register(s *Service, opts ...RegisterOption) error { var check *consul.AgentServiceCheck - // if the TTL is greater than 0 create an associated check - if options.TTL > time.Duration(0) { - // splay slightly for the watcher? - splay := time.Second * 5 - deregTTL := options.TTL + splay - // consul has a minimum timeout on deregistration of 1 minute. - if options.TTL < time.Minute { - deregTTL = time.Minute + splay + if regTCPCheck { + deregTTL := getDeregisterTTL(regInterval) + + check = &consul.AgentServiceCheck{ + TCP: fmt.Sprintf("%s:%d", node.Address, node.Port), + Interval: fmt.Sprintf("%v", regInterval), + DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL), } + // if the TTL is greater than 0 create an associated check + } else if options.TTL > time.Duration(0) { + deregTTL := getDeregisterTTL(options.TTL) + check = &consul.AgentServiceCheck{ TTL: fmt.Sprintf("%v", options.TTL), DeregisterCriticalServiceAfter: fmt.Sprintf("%v", deregTTL),