github.com/v2fly/v2ray-core/v4@v4.45.2/app/router/balancing.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package router 5 6 import ( 7 "context" 8 9 "github.com/v2fly/v2ray-core/v4/common/dice" 10 "github.com/v2fly/v2ray-core/v4/features/extension" 11 "github.com/v2fly/v2ray-core/v4/features/outbound" 12 ) 13 14 type BalancingStrategy interface { 15 PickOutbound([]string) string 16 } 17 18 type RandomStrategy struct{} 19 20 func (s *RandomStrategy) PickOutbound(tags []string) string { 21 n := len(tags) 22 if n == 0 { 23 panic("0 tags") 24 } 25 26 return tags[dice.Roll(n)] 27 } 28 29 type Balancer struct { 30 selectors []string 31 strategy BalancingStrategy 32 ohm outbound.Manager 33 } 34 35 func (b *Balancer) PickOutbound() (string, error) { 36 hs, ok := b.ohm.(outbound.HandlerSelector) 37 if !ok { 38 return "", newError("outbound.Manager is not a HandlerSelector") 39 } 40 tags := hs.Select(b.selectors) 41 if len(tags) == 0 { 42 return "", newError("no available outbounds selected") 43 } 44 tag := b.strategy.PickOutbound(tags) 45 if tag == "" { 46 return "", newError("balancing strategy returns empty tag") 47 } 48 return tag, nil 49 } 50 51 func (b *Balancer) InjectContext(ctx context.Context) { 52 if contextReceiver, ok := b.strategy.(extension.ContextReceiver); ok { 53 contextReceiver.InjectContext(ctx) 54 } 55 }