debian-mirror-gitlab/lib/gitlab/database/load_balancing/configuration.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

162 lines
5.4 KiB
Ruby
Raw Normal View History

2021-11-11 11:23:49 +05:30
# frozen_string_literal: true
module Gitlab
module Database
module LoadBalancing
# Configuration settings for a single LoadBalancer instance.
class Configuration
attr_accessor :hosts, :max_replication_difference,
:max_replication_lag_time, :replica_check_interval,
2021-12-11 22:18:48 +05:30
:service_discovery
2021-11-11 11:23:49 +05:30
# Creates a configuration object for the given ActiveRecord model.
def self.for_model(model)
cfg = model.connection_db_config.configuration_hash.deep_symbolize_keys
lb_cfg = cfg[:load_balancing] || {}
config = new(model)
if (diff = lb_cfg[:max_replication_difference])
config.max_replication_difference = diff
end
if (lag = lb_cfg[:max_replication_lag_time])
config.max_replication_lag_time = lag.to_f
end
if (interval = lb_cfg[:replica_check_interval])
config.replica_check_interval = interval.to_f
end
if (hosts = lb_cfg[:hosts])
config.hosts = hosts
end
discover = lb_cfg[:discover] || {}
# We iterate over the known/default keys so we don't end up with
# random keys in our configuration hash.
config.service_discovery.each do |key, _|
if (value = discover[key])
config.service_discovery[key] = value
end
end
2021-12-11 22:18:48 +05:30
config.reuse_primary_connection!
2021-11-11 11:23:49 +05:30
config
end
def initialize(model, hosts = [])
@max_replication_difference = 8.megabytes
@max_replication_lag_time = 60.0
@replica_check_interval = 60.0
@model = model
@hosts = hosts
@service_discovery = {
nameserver: 'localhost',
port: 8600,
record: nil,
record_type: 'A',
interval: 60,
disconnect_timeout: 120,
use_tcp: false
}
2021-12-11 22:18:48 +05:30
# Temporary model for GITLAB_LOAD_BALANCING_REUSE_PRIMARY_
# To be removed with FF
@primary_model = nil
end
def db_config_name
@model.connection_db_config.name.to_sym
end
# With connection re-use the primary connection can be overwritten
# to be used from different model
def primary_connection_specification_name
2022-04-04 11:22:00 +05:30
primary_model_or_model_if_enabled.connection_specification_name
2021-12-11 22:18:48 +05:30
end
2022-04-04 11:22:00 +05:30
def primary_model_or_model_if_enabled
2022-06-21 17:19:12 +05:30
if use_dedicated_connection?
2022-04-04 11:22:00 +05:30
@model
else
@primary_model || @model
end
end
2022-06-21 17:19:12 +05:30
def use_dedicated_connection?
return true unless @primary_model # We can only use dedicated connection, if re-use of connections is disabled
2022-04-04 11:22:00 +05:30
return false unless ::Gitlab::SafeRequestStore.active?
::Gitlab::SafeRequestStore.fetch(:force_no_sharing_primary_model) do
::Feature::FlipperFeature.table_exists? && ::Feature.enabled?(:force_no_sharing_primary_model, default_enabled: :yaml)
end
2021-12-11 22:18:48 +05:30
end
2022-05-07 20:08:51 +05:30
def primary_db_config
primary_model_or_model_if_enabled.connection_db_config
end
2021-12-11 22:18:48 +05:30
def replica_db_config
@model.connection_db_config
2021-11-11 11:23:49 +05:30
end
def pool_size
# The pool size may change when booting up GitLab, as GitLab enforces
# a certain number of threads. If a Configuration is memoized, this
# can lead to incorrect pool sizes.
#
# To support this scenario, we always attempt to read the pool size
# from the model's configuration.
@model.connection_db_config.configuration_hash[:pool] ||
Database.default_pool_size
end
2021-11-18 22:05:49 +05:30
# Returns `true` if the use of load balancing replicas should be
# enabled.
#
# This is disabled for Rake tasks to ensure e.g. database migrations
# always produce consistent results.
2021-11-11 11:23:49 +05:30
def load_balancing_enabled?
2021-11-18 22:05:49 +05:30
return false if Gitlab::Runtime.rake?
2021-11-11 11:23:49 +05:30
hosts.any? || service_discovery_enabled?
end
2022-01-26 12:08:38 +05:30
# This is disabled for Rake tasks to ensure e.g. database migrations
# always produce consistent results.
2021-11-11 11:23:49 +05:30
def service_discovery_enabled?
2022-01-26 12:08:38 +05:30
return false if Gitlab::Runtime.rake?
2021-11-11 11:23:49 +05:30
service_discovery[:record].present?
end
2021-12-11 22:18:48 +05:30
# TODO: This is temporary code to allow re-use of primary connection
# if the two connections are pointing to the same host. This is needed
# to properly support transaction visibility.
#
# This behavior is required to support [Phase 3](https://gitlab.com/groups/gitlab-org/-/epics/6160#progress).
# This method is meant to be removed as soon as it is finished.
#
# The remapping is done as-is:
# export GITLAB_LOAD_BALANCING_REUSE_PRIMARY_<name-of-connection>=<new-name-of-connection>
#
# Ex.:
# export GITLAB_LOAD_BALANCING_REUSE_PRIMARY_ci=main
#
def reuse_primary_connection!
new_connection = ENV["GITLAB_LOAD_BALANCING_REUSE_PRIMARY_#{db_config_name}"]
return unless new_connection.present?
@primary_model = Gitlab::Database.database_base_models[new_connection.to_sym]
unless @primary_model
raise "Invalid value for 'GITLAB_LOAD_BALANCING_REUSE_PRIMARY_#{db_config_name}=#{new_connection}'"
end
end
2021-11-11 11:23:49 +05:30
end
end
end
end