Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/database/load_balancing.rb')
-rw-r--r--lib/gitlab/database/load_balancing.rb97
1 files changed, 19 insertions, 78 deletions
diff --git a/lib/gitlab/database/load_balancing.rb b/lib/gitlab/database/load_balancing.rb
index 08f108eb8e4..bbfbf83222f 100644
--- a/lib/gitlab/database/load_balancing.rb
+++ b/lib/gitlab/database/load_balancing.rb
@@ -36,89 +36,42 @@ module Gitlab
# Returns a Hash containing the load balancing configuration.
def self.configuration
- Gitlab::Database.main.config[:load_balancing] || {}
- end
-
- # Returns the maximum replica lag size in bytes.
- def self.max_replication_difference
- (configuration['max_replication_difference'] || 8.megabytes).to_i
- end
-
- # Returns the maximum lag time for a replica.
- def self.max_replication_lag_time
- (configuration['max_replication_lag_time'] || 60.0).to_f
- end
-
- # Returns the interval (in seconds) to use for checking the status of a
- # replica.
- def self.replica_check_interval
- (configuration['replica_check_interval'] || 60).to_f
- end
-
- # Returns the additional hosts to use for load balancing.
- def self.hosts
- configuration['hosts'] || []
- end
-
- def self.service_discovery_enabled?
- configuration.dig('discover', 'record').present?
- end
-
- def self.service_discovery_configuration
- conf = configuration['discover'] || {}
-
- {
- nameserver: conf['nameserver'] || 'localhost',
- port: conf['port'] || 8600,
- record: conf['record'],
- record_type: conf['record_type'] || 'A',
- interval: conf['interval'] || 60,
- disconnect_timeout: conf['disconnect_timeout'] || 120,
- use_tcp: conf['use_tcp'] || false
- }
- end
-
- def self.pool_size
- Gitlab::Database.main.pool_size
+ @configuration ||= Configuration.for_model(ActiveRecord::Base)
end
# Returns true if load balancing is to be enabled.
def self.enable?
return false if Gitlab::Runtime.rake?
- return false unless self.configured?
- true
+ configured?
end
- # Returns true if load balancing has been configured. Since
- # Sidekiq does not currently use load balancing, we
- # may want Web application servers to detect replication lag by
- # posting the write location of the database if load balancing is
- # configured.
def self.configured?
- hosts.any? || service_discovery_enabled?
+ configuration.load_balancing_enabled? ||
+ configuration.service_discovery_enabled?
end
def self.start_service_discovery
- return unless service_discovery_enabled?
+ return unless configuration.service_discovery_enabled?
- ServiceDiscovery.new(service_discovery_configuration).start
+ ServiceDiscovery
+ .new(proxy.load_balancer, **configuration.service_discovery)
+ .start
end
# Configures proxying of requests.
- def self.configure_proxy(proxy = ConnectionProxy.new(hosts))
- ActiveRecord::Base.load_balancing_proxy = proxy
+ def self.configure_proxy
+ lb = LoadBalancer.new(configuration, primary_only: !enable?)
+ ActiveRecord::Base.load_balancing_proxy = ConnectionProxy.new(lb)
# Populate service discovery immediately if it is configured
- if service_discovery_enabled?
- ServiceDiscovery.new(service_discovery_configuration).perform_service_discovery
+ if configuration.service_discovery_enabled?
+ ServiceDiscovery
+ .new(lb, **configuration.service_discovery)
+ .perform_service_discovery
end
end
- def self.active_record_models
- ActiveRecord::Base.descendants
- end
-
DB_ROLES = [
ROLE_PRIMARY = :primary,
ROLE_REPLICA = :replica,
@@ -126,24 +79,12 @@ module Gitlab
].freeze
# Returns the role (primary/replica) of the database the connection is
- # connecting to. At the moment, the connection can only be retrieved by
- # Gitlab::Database::LoadBalancer#read or #read_write or from the
- # ActiveRecord directly. Therefore, if the load balancer doesn't
- # recognize the connection, this method returns the primary role
- # directly. In future, we may need to check for other sources.
+ # connecting to.
def self.db_role_for_connection(connection)
- return ROLE_UNKNOWN unless connection
-
- # The connection proxy does not have a role assigned
- # as this is dependent on a execution context
- return ROLE_UNKNOWN if connection.is_a?(ConnectionProxy)
-
- # During application init we might receive `NullPool`
- return ROLE_UNKNOWN unless connection.respond_to?(:pool) &&
- connection.pool.respond_to?(:db_config) &&
- connection.pool.db_config.respond_to?(:name)
+ db_config = Database.db_config_for_connection(connection)
+ return ROLE_UNKNOWN unless db_config
- if connection.pool.db_config.name.ends_with?(LoadBalancer::REPLICA_SUFFIX)
+ if db_config.name.ends_with?(LoadBalancer::REPLICA_SUFFIX)
ROLE_REPLICA
else
ROLE_PRIMARY