github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/balancers/balancers.go (about)

     1  package balancers
     2  
     3  import (
     4  	"slices"
     5  	"sort"
     6  	"strings"
     7  
     8  	balancerConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/config"
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/endpoint"
    10  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xstring"
    11  )
    12  
    13  // Deprecated: RoundRobin is an alias to RandomChoice now
    14  // Will be removed after Oct 2024.
    15  // Read about versioning policy: https://github.com/ydb-platform/ydb-go-sdk/blob/master/VERSIONING.md#deprecated
    16  func RoundRobin() *balancerConfig.Config {
    17  	return &balancerConfig.Config{}
    18  }
    19  
    20  func RandomChoice() *balancerConfig.Config {
    21  	return &balancerConfig.Config{}
    22  }
    23  
    24  func SingleConn() *balancerConfig.Config {
    25  	return &balancerConfig.Config{
    26  		SingleConn: true,
    27  	}
    28  }
    29  
    30  type filterLocalDC struct{}
    31  
    32  func (filterLocalDC) Allow(info balancerConfig.Info, e endpoint.Info) bool {
    33  	return e.Location() == info.SelfLocation
    34  }
    35  
    36  func (filterLocalDC) String() string {
    37  	return "LocalDC"
    38  }
    39  
    40  // Deprecated: use PreferNearestDC instead
    41  // Will be removed after March 2025.
    42  // Read about versioning policy: https://github.com/ydb-platform/ydb-go-sdk/blob/master/VERSIONING.md#deprecated
    43  func PreferLocalDC(balancer *balancerConfig.Config) *balancerConfig.Config {
    44  	balancer.Filter = filterLocalDC{}
    45  	balancer.DetectNearestDC = true
    46  
    47  	return balancer
    48  }
    49  
    50  // PreferNearestDC creates balancer which use endpoints only in location such as initial endpoint location
    51  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
    52  // PreferNearestDC balancer try to autodetect local DC from client side.
    53  func PreferNearestDC(balancer *balancerConfig.Config) *balancerConfig.Config {
    54  	balancer.Filter = filterLocalDC{}
    55  	balancer.DetectNearestDC = true
    56  
    57  	return balancer
    58  }
    59  
    60  // Deprecated: use PreferNearestDCWithFallBack instead
    61  // Will be removed after March 2025.
    62  // Read about versioning policy: https://github.com/ydb-platform/ydb-go-sdk/blob/master/VERSIONING.md#deprecated
    63  func PreferLocalDCWithFallBack(balancer *balancerConfig.Config) *balancerConfig.Config {
    64  	balancer = PreferNearestDC(balancer)
    65  	balancer.AllowFallback = true
    66  
    67  	return balancer
    68  }
    69  
    70  // PreferNearestDCWithFallBack creates balancer which use endpoints only in location such as initial endpoint location
    71  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
    72  // If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
    73  func PreferNearestDCWithFallBack(balancer *balancerConfig.Config) *balancerConfig.Config {
    74  	balancer = PreferNearestDC(balancer)
    75  	balancer.AllowFallback = true
    76  
    77  	return balancer
    78  }
    79  
    80  type filterLocations []string
    81  
    82  func (locations filterLocations) Allow(_ balancerConfig.Info, e endpoint.Info) bool {
    83  	location := strings.ToUpper(e.Location())
    84  	for _, l := range locations {
    85  		if location == l {
    86  			return true
    87  		}
    88  	}
    89  
    90  	return false
    91  }
    92  
    93  func (locations filterLocations) String() string {
    94  	buffer := xstring.Buffer()
    95  	defer buffer.Free()
    96  
    97  	buffer.WriteString("Locations{")
    98  	for i, l := range locations {
    99  		if i != 0 {
   100  			buffer.WriteByte(',')
   101  		}
   102  		buffer.WriteString(l)
   103  	}
   104  	buffer.WriteByte('}')
   105  
   106  	return buffer.String()
   107  }
   108  
   109  // PreferLocations creates balancer which use endpoints only in selected locations (such as "ABC", "DEF", etc.)
   110  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
   111  func PreferLocations(balancer *balancerConfig.Config, locations ...string) *balancerConfig.Config {
   112  	if len(locations) == 0 {
   113  		panic("empty list of locations")
   114  	}
   115  
   116  	// Prevent modify source locations
   117  	locations = slices.Clone(locations)
   118  
   119  	for i := range locations {
   120  		locations[i] = strings.ToUpper(locations[i])
   121  	}
   122  	sort.Strings(locations)
   123  	balancer.Filter = filterLocations(locations)
   124  
   125  	return balancer
   126  }
   127  
   128  // PreferLocationsWithFallback creates balancer which use endpoints only in selected locations
   129  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
   130  // If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
   131  func PreferLocationsWithFallback(balancer *balancerConfig.Config, locations ...string) *balancerConfig.Config {
   132  	balancer = PreferLocations(balancer, locations...)
   133  	balancer.AllowFallback = true
   134  
   135  	return balancer
   136  }
   137  
   138  type Endpoint interface {
   139  	NodeID() uint32
   140  	Address() string
   141  	Location() string
   142  
   143  	// Deprecated: LocalDC check "local" by compare endpoint location with discovery "selflocation" field.
   144  	// It work good only if connection url always point to local dc.
   145  	// Will be removed after Oct 2024.
   146  	// Read about versioning policy: https://github.com/ydb-platform/ydb-go-sdk/blob/master/VERSIONING.md#deprecated
   147  	LocalDC() bool
   148  }
   149  
   150  type filterFunc func(info balancerConfig.Info, e endpoint.Info) bool
   151  
   152  func (p filterFunc) Allow(info balancerConfig.Info, e endpoint.Info) bool {
   153  	return p(info, e)
   154  }
   155  
   156  func (p filterFunc) String() string {
   157  	return "Custom"
   158  }
   159  
   160  // Prefer creates balancer which use endpoints by filter
   161  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter
   162  func Prefer(balancer *balancerConfig.Config, filter func(endpoint Endpoint) bool) *balancerConfig.Config {
   163  	balancer.Filter = filterFunc(func(_ balancerConfig.Info, e endpoint.Info) bool {
   164  		return filter(e)
   165  	})
   166  
   167  	return balancer
   168  }
   169  
   170  // PreferWithFallback creates balancer which use endpoints by filter
   171  // Balancer "balancer" defines balancing algorithm between endpoints selected with filter
   172  // If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
   173  func PreferWithFallback(balancer *balancerConfig.Config, filter func(endpoint Endpoint) bool) *balancerConfig.Config {
   174  	balancer = Prefer(balancer, filter)
   175  	balancer.AllowFallback = true
   176  
   177  	return balancer
   178  }
   179  
   180  // Default balancer used by default
   181  func Default() *balancerConfig.Config {
   182  	return RandomChoice()
   183  }