mirror of
https://github.com/go-micro/go-micro.git
synced 2025-08-10 21:52:01 +02:00
Merge pull request #835 from milosgajdos83/router-strategy
Router strategy
This commit is contained in:
@@ -319,23 +319,13 @@ func (r *router) advertiseTable() error {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
// list routing table routes to announce
|
// do full table flush
|
||||||
routes, err := r.table.List()
|
events, err := r.flushRouteEvents(Update)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed listing routes: %s", err)
|
return fmt.Errorf("failed flushing routes: %s", err)
|
||||||
}
|
|
||||||
// collect all the added routes before we attempt to add default gateway
|
|
||||||
events := make([]*Event, len(routes))
|
|
||||||
for i, route := range routes {
|
|
||||||
event := &Event{
|
|
||||||
Type: Update,
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Route: route,
|
|
||||||
}
|
|
||||||
events[i] = event
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// advertise all routes as Update events to subscribers
|
// advertise routes to subscribers
|
||||||
if len(events) > 0 {
|
if len(events) > 0 {
|
||||||
log.Debugf("Router flushing table with %d events: %s", len(events), r.options.Id)
|
log.Debugf("Router flushing table with %d events: %s", len(events), r.options.Id)
|
||||||
r.advertWg.Add(1)
|
r.advertWg.Add(1)
|
||||||
@@ -692,15 +682,58 @@ func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) {
|
|||||||
return nil, fmt.Errorf("failed listing routes: %s", err)
|
return nil, fmt.Errorf("failed listing routes: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.options.Advertise == AdvertiseAll {
|
||||||
|
// build a list of events to advertise
|
||||||
|
events := make([]*Event, len(routes))
|
||||||
|
for i, route := range routes {
|
||||||
|
event := &Event{
|
||||||
|
Type: evType,
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
Route: route,
|
||||||
|
}
|
||||||
|
events[i] = event
|
||||||
|
}
|
||||||
|
return events, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// routeMap stores optimal routes per service
|
||||||
|
bestRoutes := make(map[string]Route)
|
||||||
|
|
||||||
|
// go through all routes found in the routing table and collapse them to optimal routes
|
||||||
|
for _, route := range routes {
|
||||||
|
routeKey := route.Service + "@" + route.Network
|
||||||
|
optimal, ok := bestRoutes[routeKey]
|
||||||
|
if !ok {
|
||||||
|
bestRoutes[routeKey] = route
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// if the current optimal route metric is higher than routing table route, replace it
|
||||||
|
if optimal.Metric > route.Metric {
|
||||||
|
bestRoutes[routeKey] = route
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// if the metrics are the same, prefer advertising your own route
|
||||||
|
if optimal.Metric == route.Metric {
|
||||||
|
if route.Router == r.options.Id {
|
||||||
|
bestRoutes[routeKey] = route
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Router advertising %d best routes out of %d", len(bestRoutes), len(routes))
|
||||||
|
|
||||||
// build a list of events to advertise
|
// build a list of events to advertise
|
||||||
events := make([]*Event, len(routes))
|
events := make([]*Event, len(bestRoutes))
|
||||||
for i, route := range routes {
|
i := 0
|
||||||
|
for _, route := range bestRoutes {
|
||||||
event := &Event{
|
event := &Event{
|
||||||
Type: evType,
|
Type: evType,
|
||||||
Timestamp: time.Now(),
|
Timestamp: time.Now(),
|
||||||
Route: route,
|
Route: route,
|
||||||
}
|
}
|
||||||
events[i] = event
|
events[i] = event
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
return events, nil
|
return events, nil
|
||||||
|
@@ -18,6 +18,8 @@ type Options struct {
|
|||||||
Network string
|
Network string
|
||||||
// Registry is the local registry
|
// Registry is the local registry
|
||||||
Registry registry.Registry
|
Registry registry.Registry
|
||||||
|
// Advertise is the advertising strategy
|
||||||
|
Advertise Strategy
|
||||||
// Client for calling router
|
// Client for calling router
|
||||||
Client client.Client
|
Client client.Client
|
||||||
}
|
}
|
||||||
@@ -64,12 +66,20 @@ func Registry(r registry.Registry) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strategy sets route advertising strategy
|
||||||
|
func Advertise(a Strategy) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.Advertise = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultOptions returns router default options
|
// DefaultOptions returns router default options
|
||||||
func DefaultOptions() Options {
|
func DefaultOptions() Options {
|
||||||
return Options{
|
return Options{
|
||||||
Id: uuid.New().String(),
|
Id: uuid.New().String(),
|
||||||
Address: DefaultAddress,
|
Address: DefaultAddress,
|
||||||
Network: DefaultNetwork,
|
Network: DefaultNetwork,
|
||||||
Registry: registry.DefaultRegistry,
|
Registry: registry.DefaultRegistry,
|
||||||
|
Advertise: AdvertiseBest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -139,6 +139,28 @@ type Advert struct {
|
|||||||
Events []*Event
|
Events []*Event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strategy is route advertisement strategy
|
||||||
|
type Strategy int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AdvertiseAll advertises all routes to the network
|
||||||
|
AdvertiseAll Strategy = iota
|
||||||
|
// AdvertiseBest advertises optimal routes to the network
|
||||||
|
AdvertiseBest
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns human readable Strategy
|
||||||
|
func (s Strategy) String() string {
|
||||||
|
switch s {
|
||||||
|
case AdvertiseAll:
|
||||||
|
return "all"
|
||||||
|
case AdvertiseBest:
|
||||||
|
return "best"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewRouter creates new Router and returns it
|
// NewRouter creates new Router and returns it
|
||||||
func NewRouter(opts ...Option) Router {
|
func NewRouter(opts ...Option) Router {
|
||||||
return newRouter(opts...)
|
return newRouter(opts...)
|
||||||
|
Reference in New Issue
Block a user