github.com/EagleQL/Xray-core@v1.4.3/app/router/balancing.go (about)

     1  package router
     2  
     3  import (
     4  	"github.com/xtls/xray-core/common/dice"
     5  	"github.com/xtls/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  }