github.com/micro/go-micro/examples@v0.0.0-20210105173217-bf4ab679e18b/client/dc_selector/dc_selector.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "sync" 8 "time" 9 10 "github.com/micro/go-micro/v2/client" 11 "github.com/micro/go-micro/v2/client/selector" 12 "github.com/micro/go-micro/v2/config/cmd" 13 "github.com/micro/go-micro/v2/registry" 14 15 example "github.com/micro/go-micro/examples/server/proto/example" 16 ) 17 18 // Built in random hashed node selector 19 type dcSelector struct { 20 opts selector.Options 21 } 22 23 var ( 24 datacenter = "local" 25 ) 26 27 func init() { 28 rand.Seed(time.Now().Unix()) 29 } 30 31 func (n *dcSelector) Init(opts ...selector.Option) error { 32 for _, o := range opts { 33 o(&n.opts) 34 } 35 return nil 36 } 37 38 func (n *dcSelector) Options() selector.Options { 39 return n.opts 40 } 41 42 func (n *dcSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { 43 services, err := n.opts.Registry.GetService(service) 44 if err != nil { 45 return nil, err 46 } 47 48 if len(services) == 0 { 49 return nil, selector.ErrNotFound 50 } 51 52 var nodes []*registry.Node 53 54 // Filter the nodes for datacenter 55 for _, service := range services { 56 for _, node := range service.Nodes { 57 if node.Metadata["datacenter"] == datacenter { 58 nodes = append(nodes, node) 59 } 60 } 61 } 62 63 if len(nodes) == 0 { 64 return nil, selector.ErrNotFound 65 } 66 67 var i int 68 var mtx sync.Mutex 69 70 return func() (*registry.Node, error) { 71 mtx.Lock() 72 defer mtx.Unlock() 73 i++ 74 return nodes[i%len(nodes)], nil 75 }, nil 76 } 77 78 func (n *dcSelector) Mark(service string, node *registry.Node, err error) { 79 return 80 } 81 82 func (n *dcSelector) Reset(service string) { 83 return 84 } 85 86 func (n *dcSelector) Close() error { 87 return nil 88 } 89 90 func (n *dcSelector) String() string { 91 return "dc" 92 } 93 94 // Return a new first node selector 95 func DCSelector(opts ...selector.Option) selector.Selector { 96 var sopts selector.Options 97 for _, opt := range opts { 98 opt(&sopts) 99 } 100 if sopts.Registry == nil { 101 sopts.Registry = registry.DefaultRegistry 102 } 103 return &dcSelector{sopts} 104 } 105 106 func call(i int) { 107 // Create new request to service go.micro.srv.example, method Example.Call 108 req := client.NewRequest("go.micro.srv.example", "Example.Call", &example.Request{ 109 Name: "John", 110 }) 111 112 rsp := &example.Response{} 113 114 // Call service 115 if err := client.Call(context.Background(), req, rsp); err != nil { 116 fmt.Println("call err: ", err, rsp) 117 return 118 } 119 120 fmt.Println("Call:", i, "rsp:", rsp.Msg) 121 } 122 123 func main() { 124 cmd.Init() 125 126 client.DefaultClient = client.NewClient( 127 client.Selector(DCSelector()), 128 ) 129 130 fmt.Println("\n--- Call example ---") 131 for i := 0; i < 10; i++ { 132 call(i) 133 } 134 }