micro/selector/selector.go

101 lines
2.4 KiB
Go
Raw Normal View History

2015-12-09 22:23:16 +03:00
/*
The Selector package provides a way to algorithmically filter and return
nodes required by the client or any other system. Selector's implemented
by Micro build on the registry but it's of optional use. One could
provide a static Selector that has a fixed pool.
func (r *randomSelector) Select(service string, opts ...SelectOption) (Next, error) {
var sopts SelectOptions
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 {
return nil, ErrNotFound
}
var nodes []*registry.Node
for _, service := range services {
for _, node := range service.Nodes {
nodes = append(nodes, node)
}
}
if len(nodes) == 0 {
return nil, ErrNotFound
}
return func() (*registry.Node, error) {
i := rand.Int()
j := i % len(services)
if len(services[j].Nodes) == 0 {
return nil, ErrNotFound
}
k := i % len(services[j].Nodes)
return services[j].Nodes[k], nil
}, nil
}
*/
package selector
import (
"errors"
"github.com/micro/go-micro/registry"
)
// Selector builds on the registry as a mechanism to pick nodes
// and mark their status. This allows host pools and other things
// to be built using various algorithms.
type Selector interface {
2016-01-05 02:07:56 +03:00
Init(opts ...Option) error
Options() Options
2015-12-09 22:23:16 +03:00
// Select returns a function which should return the next node
Select(service string, opts ...SelectOption) (Next, error)
// Mark sets the success/error against a node
Mark(service string, node *registry.Node, err error)
// Reset returns state back to zero for a service
Reset(service string)
// Close renders the selector unusable
Close() error
2015-12-20 00:56:14 +03:00
// Name of the selector
String() string
2015-12-09 22:23:16 +03:00
}
// Next is a function that returns the next node
2016-05-04 00:06:19 +03:00
// based on the selector's strategy
2015-12-09 22:23:16 +03:00
type Next func() (*registry.Node, error)
2016-04-23 22:15:01 +03:00
// Filter is used to filter a service during the selection process
type Filter func([]*registry.Service) []*registry.Service
2015-12-09 22:23:16 +03:00
2016-05-04 00:06:19 +03:00
// Strategy is a selection strategy e.g random, round robin
type Strategy func([]*registry.Service) Next
2015-12-09 22:23:16 +03:00
var (
2016-05-04 00:06:19 +03:00
DefaultSelector = newDefaultSelector()
2015-12-09 22:23:16 +03:00
ErrNotFound = errors.New("not found")
ErrNoneAvailable = errors.New("none available")
)
func NewSelector(opts ...Option) Selector {
2016-05-04 00:06:19 +03:00
return newDefaultSelector(opts...)
2015-12-09 22:23:16 +03:00
}