Add the notion of a node selector for routing

This commit is contained in:
Asim
2015-12-07 21:09:10 +00:00
parent 050fa26afb
commit 4e6b9347d9
4 changed files with 106 additions and 2 deletions

View File

@@ -8,10 +8,18 @@ import (
"github.com/micro/go-micro/registry"
)
// NodeSelector is used to retrieve a node to which a request
// should be routed. It takes a list of services and selects
// a single node. If a node cannot be selected it should return
// an error. A list of services is provided as a service may
// have 1 or more versions.
type NodeSelector func(service []*registry.Service) (*registry.Node, error)
func init() {
rand.Seed(time.Now().UnixNano())
}
// Built in random hashed node selector
func nodeSelector(service []*registry.Service) (*registry.Node, error) {
if len(service) == 0 {
return nil, errors.NotFound("go.micro.client", "Service not found")

View File

@@ -14,6 +14,7 @@ type options struct {
registry registry.Registry
transport transport.Transport
wrappers []Wrapper
selector NodeSelector
}
// Broker to be used for pub/sub
@@ -51,6 +52,13 @@ func Transport(t transport.Transport) Option {
}
}
// Selector is used to select a node to route a request to
func Selector(s NodeSelector) Option {
return func(o *options) {
o.selector = s
}
}
// Adds a Wrapper to a list of options passed into the client
func Wrap(w Wrapper) Option {
return func(o *options) {

View File

@@ -43,6 +43,10 @@ func newRpcClient(opt ...Option) Client {
opts.broker = broker.DefaultBroker
}
if opts.selector == nil {
opts.selector = nodeSelector
}
rc := &rpcClient{
once: once,
opts: opts,
@@ -146,7 +150,7 @@ func (r *rpcClient) Call(ctx context.Context, request Request, response interfac
return errors.InternalServerError("go.micro.client", err.Error())
}
node, err := nodeSelector(service)
node, err := r.opts.selector(service)
if err != nil {
return err
}
@@ -169,7 +173,7 @@ func (r *rpcClient) Stream(ctx context.Context, request Request, responseChan in
return nil, errors.InternalServerError("go.micro.client", err.Error())
}
node, err := nodeSelector(service)
node, err := r.opts.selector(service)
if err != nil {
return nil, err
}