diff --git a/registry/consul_registry.go b/registry/consul_registry.go index a3387dba..366b77fd 100644 --- a/registry/consul_registry.go +++ b/registry/consul_registry.go @@ -115,6 +115,19 @@ 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") @@ -155,16 +168,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 options.TCPCheck { + deregTTL := getDeregisterTTL(options.Interval) + + check = &consul.AgentServiceCheck{ + TCP: c.Address, + Interval: fmt.Sprintf("%v", options.Interval), + 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), diff --git a/registry/options.go b/registry/options.go index aa9c3f4f..086b599d 100644 --- a/registry/options.go +++ b/registry/options.go @@ -18,7 +18,9 @@ type Options struct { } type RegisterOptions struct { - TTL time.Duration + TCPCheck bool + TTL time.Duration + Interval time.Duration // Other options for implementations of the interface // can be stored in a context Context context.Context @@ -66,6 +68,23 @@ func RegisterTTL(t time.Duration) RegisterOption { } } +// +// RegisterTCPCheck 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. +// This option is for registry using Consul, see `TCP + Interval` more +// information [1]. +// +// [1] https://www.consul.io/docs/agent/checks.html +// +func RegisterTCPCheck(t time.Duration) RegisterOption { + return func(o *RegisterOptions) { + if t > time.Duration(0) { + o.TCPCheck = true + o.Interval = t + } + } +} + // Watch a service func WatchService(name string) WatchOption { return func(o *WatchOptions) { diff --git a/server/options.go b/server/options.go index 5b9aa98e..5fd4e4bb 100644 --- a/server/options.go +++ b/server/options.go @@ -25,7 +25,9 @@ type Options struct { HdlrWrappers []HandlerWrapper SubWrappers []SubscriberWrapper - RegisterTTL time.Duration + RegisterTCPCheck bool + RegisterTTL time.Duration + RegisterInterval time.Duration // Debug Handler which can be set by a user DebugHandler debug.DebugHandler @@ -164,6 +166,23 @@ func RegisterTTL(t time.Duration) Option { } } +// +// RegisterTCPCheck 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. +// This option is for registry using Consul, see `TCP + Interval` more +// information [1]. +// +// [1] https://www.consul.io/docs/agent/checks.html +// +func RegisterTCPCheck(t time.Duration) Option { + return func(o *Options) { + if t > time.Duration(0) { + o.RegisterTCPCheck = true + o.RegisterInterval = t + } + } +} + // Wait tells the server to wait for requests to finish before exiting func Wait(b bool) Option { return func(o *Options) { diff --git a/server/rpc_server.go b/server/rpc_server.go index aa1285d9..f1ec257b 100644 --- a/server/rpc_server.go +++ b/server/rpc_server.go @@ -278,7 +278,10 @@ func (s *rpcServer) Register() error { } // create registry options - rOpts := []registry.RegisterOption{registry.RegisterTTL(config.RegisterTTL)} + rOpts := []registry.RegisterOption{ + registry.RegisterTTL(config.RegisterTTL), + registry.RegisterTCPCheck(config.RegisterInterval), + } if err := config.Registry.Register(service, rOpts...); err != nil { return err