From f9da55e8a9d4fa6ca54984170fe647248185e266 Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Mon, 7 Jan 2019 07:41:26 +0000 Subject: [PATCH] Add dns selector --- cmd/cmd.go | 2 + selector/dns/dns.go | 100 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 selector/dns/dns.go diff --git a/cmd/cmd.go b/cmd/cmd.go index 7d41b452..5793b48f 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -26,6 +26,7 @@ import ( // selectors "github.com/micro/go-micro/selector" + "github.com/micro/go-micro/selector/dns" // transports "github.com/micro/go-micro/transport" @@ -177,6 +178,7 @@ var ( DefaultSelectors = map[string]func(...selector.Option) selector.Selector{ "default": selector.NewSelector, + "dns": dns.NewSelector, "cache": selector.NewSelector, } diff --git a/selector/dns/dns.go b/selector/dns/dns.go new file mode 100644 index 00000000..05f493cc --- /dev/null +++ b/selector/dns/dns.go @@ -0,0 +1,100 @@ +// Package dns provides a dns SRV selector +package dns + +import ( + "net" + + "github.com/micro/go-micro/registry" + "github.com/micro/go-micro/selector" +) + +type dnsSelector struct { + options selector.Options + domain string +} + +var ( + DefaultDomain = "local" +) + +func (d *dnsSelector) Init(opts ...selector.Option) error { + for _, o := range opts { + o(&d.options) + } + return nil +} + +func (d *dnsSelector) Options() selector.Options { + return d.options +} + +func (d *dnsSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { + _, srv, err := net.LookupSRV(service, "tcp", d.domain) + if err != nil { + return nil, err + } + + var nodes []*registry.Node + for _, node := range srv { + nodes = append(nodes, ®istry.Node{ + Id: node.Target, + Address: node.Target, + Port: int(node.Port), + }) + } + + services := []*registry.Service{ + ®istry.Service{ + Name: service, + Nodes: nodes, + }, + } + + sopts := selector.SelectOptions{ + Strategy: d.options.Strategy, + } + + for _, opt := range opts { + opt(&sopts) + } + + // apply the filters + for _, filter := range sopts.Filters { + services = filter(services) + } + + // if there's nothing left, return + if len(services) == 0 { + return nil, selector.ErrNoneAvailable + } + + return sopts.Strategy(services), nil +} + +func (d *dnsSelector) Mark(service string, node *registry.Node, err error) { + return +} + +func (d *dnsSelector) Reset(service string) { + return +} + +func (d *dnsSelector) Close() error { + return nil +} + +func (d *dnsSelector) String() string { + return "dns" +} + +func NewSelector(opts ...selector.Option) selector.Selector { + options := selector.Options{ + Strategy: selector.Random, + } + + for _, o := range opts { + o(&options) + } + + return &dnsSelector{options: options, domain: DefaultDomain} +}