micro/client/util.go

51 lines
1.9 KiB
Go
Raw Permalink Normal View History

package client
import (
"math/rand"
"github.com/micro/go-micro/v3/errors"
"github.com/micro/go-micro/v3/router"
"github.com/micro/go-micro/v3/selector"
pnet "github.com/micro/go-micro/v3/util/net"
)
// LookupRoute for a request using the router and then choose one using the selector
func LookupRoute(req Request, opts CallOptions) (*router.Route, error) {
// check to see if the proxy has been set, if it has we don't need to lookup the routes; net.Proxy
// returns a slice of addresses, so we'll use a random one. Eventually we should to use the
// selector for this.
service, addresses, _ := pnet.Proxy(req.Service(), opts.Address)
if len(addresses) > 0 {
return &router.Route{
Service: service,
Address: addresses[rand.Int()%len(addresses)],
}, nil
}
// construct the router query
query := []router.QueryOption{router.QueryService(req.Service())}
// if a custom network was requested, pass this to the router. By default the router will use it's
// own network, which is set during initialisation.
if len(opts.Network) > 0 {
query = append(query, router.QueryNetwork(opts.Network))
}
// lookup the routes which can be used to execute the request
routes, err := opts.Router.Lookup(query...)
if err == router.ErrRouteNotFound {
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", req.Service(), err.Error())
} else if err != nil {
return nil, errors.InternalServerError("go.micro.client", "error getting next %s node: %s", req.Service(), err.Error())
}
// select the route to use for the request
if route, err := opts.Selector.Select(routes, opts.SelectOptions...); err == selector.ErrNoneAvailable {
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", req.Service(), err.Error())
} else if err != nil {
return nil, errors.InternalServerError("go.micro.client", "error getting next %s node: %s", req.Service(), err.Error())
} else {
return route, nil
}
}