micro/selector/roundrobin/round_robin_selector.go

104 lines
1.8 KiB
Go
Raw Normal View History

2015-12-09 19:23:16 +00:00
package roundrobin
2015-12-09 00:02:45 +00:00
import (
"sync"
2015-12-09 19:23:16 +00:00
2015-12-09 19:38:50 +00:00
"github.com/micro/go-micro/cmd"
2015-12-09 19:23:16 +00:00
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/selector"
2015-12-09 00:02:45 +00:00
)
type roundRobinSelector struct {
2015-12-09 19:23:16 +00:00
so selector.Options
2015-12-09 00:02:45 +00:00
}
2015-12-09 19:38:50 +00:00
func init() {
2016-01-01 01:29:40 +00:00
cmd.DefaultSelectors["roundrobin"] = NewSelector
2015-12-09 19:38:50 +00:00
}
2016-01-04 23:07:56 +00:00
func (r *roundRobinSelector) Init(opts ...selector.Option) error {
for _, o := range opts {
o(&r.so)
}
return nil
}
func (r *roundRobinSelector) Options() selector.Options {
return r.so
}
2015-12-09 19:23:16 +00:00
func (r *roundRobinSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) {
var sopts selector.SelectOptions
2015-12-09 00:02:45 +00:00
for _, opt := range opts {
opt(&sopts)
}
// get the service
services, err := r.so.Registry.GetService(service)
if err != nil {
return nil, err
}
// apply the filters
for _, filter := range sopts.Filters {
services = filter(services)
}
// if there's nothing left, return
if len(services) == 0 {
2015-12-09 19:23:16 +00:00
return nil, selector.ErrNotFound
2015-12-09 00:02:45 +00:00
}
2015-12-09 19:23:16 +00:00
var nodes []*registry.Node
2015-12-09 00:02:45 +00:00
for _, service := range services {
for _, node := range service.Nodes {
nodes = append(nodes, node)
}
}
if len(nodes) == 0 {
2015-12-09 19:23:16 +00:00
return nil, selector.ErrNotFound
2015-12-09 00:02:45 +00:00
}
var i int
var mtx sync.Mutex
2015-12-09 19:23:16 +00:00
return func() (*registry.Node, error) {
2015-12-09 00:02:45 +00:00
mtx.Lock()
defer mtx.Unlock()
i++
return nodes[i%len(nodes)], nil
}, nil
}
2015-12-09 19:23:16 +00:00
func (r *roundRobinSelector) Mark(service string, node *registry.Node, err error) {
2015-12-09 00:02:45 +00:00
return
}
func (r *roundRobinSelector) Reset(service string) {
return
}
func (r *roundRobinSelector) Close() error {
return nil
}
2015-12-19 21:56:14 +00:00
func (r *roundRobinSelector) String() string {
return "roundrobin"
}
2015-12-09 19:38:50 +00:00
func NewSelector(opts ...selector.Option) selector.Selector {
2015-12-09 19:23:16 +00:00
var sopts selector.Options
2015-12-09 00:02:45 +00:00
for _, opt := range opts {
opt(&sopts)
}
if sopts.Registry == nil {
2015-12-09 19:23:16 +00:00
sopts.Registry = registry.DefaultRegistry
2015-12-09 00:02:45 +00:00
}
return &roundRobinSelector{sopts}
}