Class: Gitlab::Database::LoadBalancing::ServiceDiscovery::Sampler
- Inherits:
-
Object
- Object
- Gitlab::Database::LoadBalancing::ServiceDiscovery::Sampler
- Defined in:
- lib/gitlab/database/load_balancing/service_discovery/sampler.rb
Instance Method Summary collapse
-
#initialize(max_replica_pools:, seed: Random.new_seed) ⇒ Sampler
constructor
A new instance of Sampler.
- #sample(addresses) ⇒ Object
Constructor Details
#initialize(max_replica_pools:, seed: Random.new_seed) ⇒ Sampler
Returns a new instance of Sampler.
8 9 10 11 12 13 14 |
# File 'lib/gitlab/database/load_balancing/service_discovery/sampler.rb', line 8 def initialize(max_replica_pools:, seed: Random.new_seed) # seed must be set once and consistent # for every invocation of #sample on # the same instance of Sampler @seed = seed @max_replica_pools = max_replica_pools end |
Instance Method Details
#sample(addresses) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/gitlab/database/load_balancing/service_discovery/sampler.rb', line 16 def sample(addresses) return addresses if @max_replica_pools.nil? || addresses.count <= @max_replica_pools ::Gitlab::Database::LoadBalancing::Logger.debug( event: :host_list_limit_exceeded, message: "Host list length exceeds max_replica_pools so random hosts will be chosen.", max_replica_pools: @max_replica_pools, total_host_list_length: addresses.count, randomization_seed: @seed ) # First sort them in case the ordering from DNS server changes # then randomly order all addresses using consistent seed so # this process always gives the same set for this instance of # Sampler addresses = addresses.sort addresses = addresses.shuffle(random: Random.new(@seed)) # Group by hostname so that we can sample evenly across hosts addresses_by_host = addresses.group_by(&:hostname) selected_addresses = [] while selected_addresses.count < @max_replica_pools # Loop over all hostnames grabbing one address at a time to # evenly distribute across all hostnames addresses_by_host.each do |host, addresses| next if addresses.empty? selected_addresses << addresses.pop break unless selected_addresses.count < @max_replica_pools end end selected_addresses end |