#224 add fifo strategy for node selector

This commit is contained in:
zhengrui 2018-03-18 10:41:55 +08:00
parent 5cf657773f
commit 22a4d48cf9
2 changed files with 30 additions and 9 deletions

View File

@ -488,7 +488,7 @@ func (r *route) serve() error {
case "sni": case "sni":
handler = gost.SNIHandler(handlerOptions...) handler = gost.SNIHandler(handlerOptions...)
default: default:
// start from 2.5, if remote is not empty, then we assume that it is a forward tunnel // start from 2.5, if remote is not empty, then we assume that it is a forward tunnel.
if node.Remote != "" { if node.Remote != "" {
handler = gost.TCPDirectForwardHandler(node.Remote, handlerOptions...) handler = gost.TCPDirectForwardHandler(node.Remote, handlerOptions...)
} else { } else {
@ -696,6 +696,8 @@ func parseStrategy(s string) gost.Strategy {
switch s { switch s {
case "random": case "random":
return &gost.RandomStrategy{} return &gost.RandomStrategy{}
case "fifo":
return &gost.FIFOStrategy{}
case "round": case "round":
fallthrough fallthrough
default: default:

View File

@ -9,7 +9,7 @@ import (
) )
var ( var (
// ErrNoneAvailable indicates there is no node available // ErrNoneAvailable indicates there is no node available.
ErrNoneAvailable = errors.New("none available") ErrNoneAvailable = errors.New("none available")
) )
@ -38,10 +38,10 @@ func (s *defaultSelector) Select(nodes []Node, opts ...SelectOption) (Node, erro
return sopts.Strategy.Apply(nodes), nil return sopts.Strategy.Apply(nodes), nil
} }
// SelectOption used when making a select call // SelectOption is the option used when making a select call.
type SelectOption func(*SelectOptions) type SelectOption func(*SelectOptions)
// SelectOptions is the options for node selection // SelectOptions is the options for node selection.
type SelectOptions struct { type SelectOptions struct {
Filters []Filter Filters []Filter
Strategy Strategy Strategy Strategy
@ -62,18 +62,19 @@ func WithStrategy(s Strategy) SelectOption {
} }
} }
// Strategy is a selection strategy e.g random, round robin // Strategy is a selection strategy e.g random, round-robin.
type Strategy interface { type Strategy interface {
Apply([]Node) Node Apply([]Node) Node
String() string String() string
} }
// RoundStrategy is a strategy for node selector // RoundStrategy is a strategy for node selector.
// The node will be selected by round-robin algorithm.
type RoundStrategy struct { type RoundStrategy struct {
count uint64 count uint64
} }
// Apply applies the round robin strategy for the nodes // Apply applies the round-robin strategy for the nodes.
func (s *RoundStrategy) Apply(nodes []Node) Node { func (s *RoundStrategy) Apply(nodes []Node) Node {
if len(nodes) == 0 { if len(nodes) == 0 {
return Node{} return Node{}
@ -87,14 +88,15 @@ func (s *RoundStrategy) String() string {
return "round" return "round"
} }
// RandomStrategy is a strategy for node selector // RandomStrategy is a strategy for node selector.
// The node will be selected randomly.
type RandomStrategy struct { type RandomStrategy struct {
Seed int64 Seed int64
rand *rand.Rand rand *rand.Rand
once sync.Once once sync.Once
} }
// Apply applies the random strategy for the nodes // Apply applies the random strategy for the nodes.
func (s *RandomStrategy) Apply(nodes []Node) Node { func (s *RandomStrategy) Apply(nodes []Node) Node {
s.once.Do(func() { s.once.Do(func() {
seed := s.Seed seed := s.Seed
@ -114,6 +116,23 @@ func (s *RandomStrategy) String() string {
return "random" return "random"
} }
// FIFOStrategy is a strategy for node selector.
// The node will be selected from first to last,
// and will stick to the selected node until it is failed.
type FIFOStrategy struct{}
// Apply applies the fifo strategy for the nodes.
func (s *FIFOStrategy) Apply(nodes []Node) Node {
if len(nodes) == 0 {
return Node{}
}
return nodes[0]
}
func (s *FIFOStrategy) String() string {
return "fifo"
}
// Filter is used to filter a node during the selection process // Filter is used to filter a node during the selection process
type Filter interface { type Filter interface {
Filter([]Node) []Node Filter([]Node) []Node