github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/proxy/balancer/balancer.go (about)

     1  // Package balancer provides a simple interface to create concrete balancer algorightms that can be used to choose
     2  // an upstream
     3  package balancer
     4  
     5  import (
     6  	"errors"
     7  	"math/rand"
     8  	"reflect"
     9  	"time"
    10  )
    11  
    12  var (
    13  	// ErrEmptyBackendList is used when the list of beckends is empty
    14  	ErrEmptyBackendList = errors.New("can not elect backend, Backends empty")
    15  	// ErrCannotElectBackend is used a backend cannot be elected
    16  	ErrCannotElectBackend = errors.New("cant elect backend")
    17  	// ErrUnsupportedAlgorithm is used when an unsupported algorithm is given
    18  	ErrUnsupportedAlgorithm = errors.New("unsupported balancing algorithm")
    19  	typeRegistry            = make(map[string]reflect.Type)
    20  )
    21  
    22  type (
    23  	// Balancer holds the load balancer methods for many different algorithms
    24  	Balancer interface {
    25  		Elect(hosts []*Target) (*Target, error)
    26  	}
    27  
    28  	// Target is an ip address/hostname with a port that identifies an instance of a backend service
    29  	Target struct {
    30  		Target string
    31  		Weight int
    32  	}
    33  )
    34  
    35  func init() {
    36  	rand.Seed(time.Now().UnixNano())
    37  	typeRegistry["roundrobin"] = reflect.TypeOf(RoundrobinBalancer{})
    38  	typeRegistry["rr"] = reflect.TypeOf(RoundrobinBalancer{})
    39  	typeRegistry["weight"] = reflect.TypeOf(WeightBalancer{})
    40  }
    41  
    42  // New creates a new Balancer based on balancing strategy
    43  func New(balance string) (Balancer, error) {
    44  	alg, ok := typeRegistry[balance]
    45  	if !ok {
    46  		return nil, ErrUnsupportedAlgorithm
    47  	}
    48  
    49  	return reflect.New(alg).Elem().Addr().Interface().(Balancer), nil
    50  }