github.com/eagleql/xray-core@v1.4.4/app/router/balancing.go (about) 1 package router 2 3 import ( 4 "github.com/eagleql/xray-core/common/dice" 5 "github.com/eagleql/xray-core/features/outbound" 6 ) 7 8 type BalancingStrategy interface { 9 PickOutbound([]string) string 10 } 11 12 type RandomStrategy struct { 13 } 14 15 func (s *RandomStrategy) PickOutbound(tags []string) string { 16 n := len(tags) 17 if n == 0 { 18 panic("0 tags") 19 } 20 21 return tags[dice.Roll(n)] 22 } 23 24 type Balancer struct { 25 selectors []string 26 strategy BalancingStrategy 27 ohm outbound.Manager 28 } 29 30 func (b *Balancer) PickOutbound() (string, error) { 31 hs, ok := b.ohm.(outbound.HandlerSelector) 32 if !ok { 33 return "", newError("outbound.Manager is not a HandlerSelector") 34 } 35 tags := hs.Select(b.selectors) 36 if len(tags) == 0 { 37 return "", newError("no available outbounds selected") 38 } 39 tag := b.strategy.PickOutbound(tags) 40 if tag == "" { 41 return "", newError("balancing strategy returns empty tag") 42 } 43 return tag, nil 44 }