Commit a309f510 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'symbol_rails_db_config' into 'master'

Use symbols to access db config

See merge request gitlab-org/gitlab!61095
parents de42badc e84d9fc6
...@@ -20,25 +20,15 @@ Gitlab.ee do ...@@ -20,25 +20,15 @@ Gitlab.ee do
end end
end end
# We configure the database connection pool size automatically based on the
# configured concurrency. We also add some headroom, to make sure we don't run
# out of connections when more threads besides the 'user-facing' ones are
# running.
#
# Read more about this in doc/development/database/client_side_connection_pool.md
headroom = (ENV["DB_POOL_HEADROOM"].presence || 10).to_i
calculated_pool_size = Gitlab::Runtime.max_threads + headroom
db_config = Gitlab::Database.config || db_config = Gitlab::Database.config ||
Rails.application.config.database_configuration[Rails.env] Rails.application.config.database_configuration[Rails.env]
db_config['pool'] = calculated_pool_size db_config['pool'] = Gitlab::Database.default_pool_size
ActiveRecord::Base.establish_connection(db_config) ActiveRecord::Base.establish_connection(db_config)
Gitlab.ee do Gitlab.ee do
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured? if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
Rails.configuration.geo_database['pool'] = calculated_pool_size Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size
Geo::TrackingBase.establish_connection(Rails.configuration.geo_database) Geo::TrackingBase.establish_connection(Rails.configuration.geo_database)
end end
end end
...@@ -19,9 +19,7 @@ module EE ...@@ -19,9 +19,7 @@ module EE
# Disables prepared statements for the current database connection. # Disables prepared statements for the current database connection.
def disable_prepared_statements def disable_prepared_statements
config = ActiveRecord::Base.configurations[Rails.env] config = ::Gitlab::Database.config.merge(prepared_statements: false)
config['prepared_statements'] = false
ActiveRecord::Base.establish_connection(config) ActiveRecord::Base.establish_connection(config)
end end
......
...@@ -36,7 +36,7 @@ module Gitlab ...@@ -36,7 +36,7 @@ module Gitlab
# Returns a Hash containing the load balancing configuration. # Returns a Hash containing the load balancing configuration.
def self.configuration def self.configuration
ActiveRecord::Base.configurations[Rails.env]['load_balancing'] || {} Gitlab::Database.config[:load_balancing] || {}
end end
# Returns the maximum replica lag size in bytes. # Returns the maximum replica lag size in bytes.
...@@ -79,7 +79,7 @@ module Gitlab ...@@ -79,7 +79,7 @@ module Gitlab
end end
def self.pool_size def self.pool_size
ActiveRecord::Base.configurations[Rails.env]['pool'] Gitlab::Database.config[:pool]
end end
# Returns true if load balancing is to be enabled. # Returns true if load balancing is to be enabled.
......
...@@ -34,14 +34,13 @@ RSpec.describe Gitlab::Database::LoadBalancing do ...@@ -34,14 +34,13 @@ RSpec.describe Gitlab::Database::LoadBalancing do
describe '.configuration' do describe '.configuration' do
it 'returns a Hash' do it 'returns a Hash' do
config = { 'hosts' => %w(foo) } lb_config = { 'hosts' => %w(foo) }
allow(ActiveRecord::Base.configurations[Rails.env]) original_db_config = Gitlab::Database.config
.to receive(:[]) modified_db_config = original_db_config.merge(load_balancing: lb_config)
.with('load_balancing') expect(Gitlab::Database).to receive(:config).and_return(modified_db_config)
.and_return(config)
expect(described_class.configuration).to eq(config) expect(described_class.configuration).to eq(lb_config)
end end
end end
...@@ -436,7 +435,8 @@ RSpec.describe Gitlab::Database::LoadBalancing do ...@@ -436,7 +435,8 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end end
shared_context 'LoadBalancing setup' do shared_context 'LoadBalancing setup' do
let(:hosts) { [ActiveRecord::Base.configurations["development"]['host']] } let(:development_db_config) { ActiveRecord::Base.configurations.default_hash("development").with_indifferent_access }
let(:hosts) { [development_db_config[:host]] }
let(:model) do let(:model) do
Class.new(ApplicationRecord) do Class.new(ApplicationRecord) do
self.table_name = "load_balancing_test" self.table_name = "load_balancing_test"
...@@ -452,10 +452,11 @@ RSpec.describe Gitlab::Database::LoadBalancing do ...@@ -452,10 +452,11 @@ RSpec.describe Gitlab::Database::LoadBalancing do
clear_load_balancing_configuration clear_load_balancing_configuration
allow(ActiveRecord::Base.singleton_class).to receive(:prepend) allow(ActiveRecord::Base.singleton_class).to receive(:prepend)
subject.configure_proxy(::Gitlab::Database::LoadBalancing::ConnectionProxy.new(hosts)) subject.configure_proxy(::Gitlab::Database::LoadBalancing::ConnectionProxy.new(hosts))
allow(ActiveRecord::Base.configurations[Rails.env])
.to receive(:[]) original_db_config = Gitlab::Database.config
.with('load_balancing') modified_db_config = original_db_config.merge(load_balancing: { hosts: hosts })
.and_return('hosts' => hosts) allow(Gitlab::Database).to receive(:config).and_return(modified_db_config)
::Gitlab::Database::LoadBalancing::Session.clear_session ::Gitlab::Database::LoadBalancing::Session.clear_session
end end
end end
......
...@@ -43,8 +43,27 @@ module Gitlab ...@@ -43,8 +43,27 @@ module Gitlab
# It does not include the default public schema # It does not include the default public schema
EXTRA_SCHEMAS = [DYNAMIC_PARTITIONS_SCHEMA, STATIC_PARTITIONS_SCHEMA].freeze EXTRA_SCHEMAS = [DYNAMIC_PARTITIONS_SCHEMA, STATIC_PARTITIONS_SCHEMA].freeze
DEFAULT_POOL_HEADROOM = 10
# We configure the database connection pool size automatically based on the
# configured concurrency. We also add some headroom, to make sure we don't run
# out of connections when more threads besides the 'user-facing' ones are
# running.
#
# Read more about this in doc/development/database/client_side_connection_pool.md
def self.default_pool_size
headroom = (ENV["DB_POOL_HEADROOM"].presence || DEFAULT_POOL_HEADROOM).to_i
Gitlab::Runtime.max_threads + headroom
end
def self.config def self.config
ActiveRecord::Base.configurations[Rails.env] default_config_hash = ActiveRecord::Base.configurations.find_db_config(Rails.env)&.config || {}
default_config_hash.with_indifferent_access.tap do |hash|
# Match config/initializers/database_config.rb
hash[:pool] ||= default_pool_size
end
end end
def self.username def self.username
...@@ -225,9 +244,9 @@ module Gitlab ...@@ -225,9 +244,9 @@ module Gitlab
env = Rails.env env = Rails.env
original_config = ActiveRecord::Base.configurations.to_h original_config = ActiveRecord::Base.configurations.to_h
env_config = original_config[env].merge('pool' => pool_size) env_config = original_config[env].with_indifferent_access.merge(pool: pool_size)
env_config['host'] = host if host env_config[:host] = host if host
env_config['port'] = port if port env_config[:port] = port if port
config = ActiveRecord::DatabaseConfigurations.new( config = ActiveRecord::DatabaseConfigurations.new(
original_config.merge(env => env_config) original_config.merge(env => env_config)
......
...@@ -87,7 +87,7 @@ module Gitlab ...@@ -87,7 +87,7 @@ module Gitlab
def max_threads def max_threads
threads = 1 # main thread threads = 1 # main thread
if puma? if puma? && Puma.respond_to?(:cli_config)
threads += Puma.cli_config.options[:max_threads] threads += Puma.cli_config.options[:max_threads]
elsif sidekiq? elsif sidekiq?
# An extra thread for the poller in Sidekiq Cron: # An extra thread for the poller in Sidekiq Cron:
......
...@@ -15,9 +15,29 @@ RSpec.describe Gitlab::Database do ...@@ -15,9 +15,29 @@ RSpec.describe Gitlab::Database do
end end
end end
describe '.default_pool_size' do
before do
allow(Gitlab::Runtime).to receive(:max_threads).and_return(7)
end
it 'returns the max thread size plus a fixed headroom of 10' do
expect(described_class.default_pool_size).to eq(17)
end
it 'returns the max thread size plus a DB_POOL_HEADROOM if this env var is present' do
stub_env('DB_POOL_HEADROOM', '7')
expect(described_class.default_pool_size).to eq(14)
end
end
describe '.config' do describe '.config' do
it 'returns a Hash' do it 'returns a HashWithIndifferentAccess' do
expect(described_class.config).to be_an_instance_of(Hash) expect(described_class.config).to be_an_instance_of(HashWithIndifferentAccess)
end
it 'returns a default pool size' do
expect(described_class.config).to include(pool: described_class.default_pool_size)
end end
end end
......
...@@ -42,7 +42,19 @@ RSpec.describe Gitlab::Runtime do ...@@ -42,7 +42,19 @@ RSpec.describe Gitlab::Runtime do
end end
end end
context "puma" do # Puma has no cli_config method unless `puma/cli` is required
context "puma without cli_config" do
let(:puma_type) { double('::Puma') }
before do
stub_const('::Puma', puma_type)
stub_env('ACTION_CABLE_IN_APP', 'false')
end
it_behaves_like "valid runtime", :puma, 1
end
context "puma with cli_config" do
let(:puma_type) { double('::Puma') } let(:puma_type) { double('::Puma') }
let(:max_workers) { 2 } let(:max_workers) { 2 }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment