diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 9bdf1aa0082a606387b63f8ce78239bf8dc5b9fa..0493dc47b86ecf99c9c81b201db5cbdea44ecf48 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -761,7 +761,6 @@ RSpec/TimecopFreeze: - 'ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_time_summary_spec.rb' - 'ee/spec/lib/gitlab/analytics/type_of_work/tasks_by_type_spec.rb' - 'ee/spec/lib/gitlab/auth/group_saml/sso_enforcer_spec.rb' - - 'ee/spec/lib/gitlab/database/load_balancing/host_spec.rb' - 'ee/spec/lib/gitlab/geo/base_request_spec.rb' - 'ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb' - 'ee/spec/lib/gitlab/geo/git_push_http_spec.rb' @@ -2915,7 +2914,6 @@ Style/RegexpLiteralMixedPreserve: - 'ee/spec/controllers/groups/groups_controller_spec.rb' - 'ee/spec/features/groups/saml_enforcement_spec.rb' - 'ee/spec/features/markdown/metrics_spec.rb' - - 'ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb' - 'ee/spec/services/jira/requests/issues/list_service_spec.rb' - 'lib/api/invitations.rb' - 'lib/gitlab/ci/pipeline/expression/lexeme/pattern.rb' diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 5e5bc00458efd0702e82c6c185b0b4f670335f3e..a93348a3b270c5b786573e6644df582661bf06e4 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -53,10 +53,12 @@ def self.safe_find_or_create_by!(*args, &block) # Start a new transaction with a shorter-than-usual statement timeout. This is # currently one third of the default 15-second timeout def self.with_fast_read_statement_timeout(timeout_ms = 5000) - transaction(requires_new: true) do - connection.exec_query("SET LOCAL statement_timeout = #{timeout_ms}") + ::Gitlab::Database::LoadBalancing::Session.current.fallback_to_replicas_for_ambiguous_queries do + transaction(requires_new: true) do + connection.exec_query("SET LOCAL statement_timeout = #{timeout_ms}") - yield + yield + end end end @@ -85,5 +87,3 @@ def self.declarative_enum(enum_mod) enum(enum_mod.key => values) end end - -ApplicationRecord.prepend_mod_with('ApplicationRecordHelpers') diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 7502a6299aeae94e9283579fba8adeada8595948..a8a6e87179ae7cfc5473686660c3a99c7073fe3e 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -1,25 +1,18 @@ # frozen_string_literal: true -# We need to run this initializer after migrations are done so it doesn't fail on CI +if Gitlab::Database::LoadBalancing.enable? + Gitlab::Database.disable_prepared_statements -Gitlab.ee do - if Gitlab::Database.cached_table_exists?('licenses') - if Gitlab::Database::LoadBalancing.enable? - Gitlab::Database.disable_prepared_statements - - Gitlab::Application.configure do |config| - config.middleware.use(Gitlab::Database::LoadBalancing::RackMiddleware) - end - - Gitlab::Database::LoadBalancing.configure_proxy + Gitlab::Application.configure do |config| + config.middleware.use(Gitlab::Database::LoadBalancing::RackMiddleware) + end - # This needs to be executed after fork of clustered processes - Gitlab::Cluster::LifecycleEvents.on_worker_start do - # Service discovery must be started after configuring the proxy, as service - # discovery depends on this. - Gitlab::Database::LoadBalancing.start_service_discovery - end + Gitlab::Database::LoadBalancing.configure_proxy - end + # This needs to be executed after fork of clustered processes + Gitlab::Cluster::LifecycleEvents.on_worker_start do + # Service discovery must be started after configuring the proxy, as service + # discovery depends on this. + Gitlab::Database::LoadBalancing.start_service_discovery end end diff --git a/ee/app/models/ee/application_record_helpers.rb b/ee/app/models/ee/application_record_helpers.rb deleted file mode 100644 index d023935d52e869ce043fb1d3427e8e069c2fdea0..0000000000000000000000000000000000000000 --- a/ee/app/models/ee/application_record_helpers.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module EE - # Intentionally pick a different name, to prevent naming conflicts - module ApplicationRecordHelpers - extend ActiveSupport::Concern - - class_methods do - extend ::Gitlab::Utils::Override - - override :with_fast_read_statement_timeout - def with_fast_read_statement_timeout(timeout_ms = 5000) - ::Gitlab::Database::LoadBalancing::Session.current.fallback_to_replicas_for_ambiguous_queries do - super - end - end - end - end -end diff --git a/ee/lib/ee/gitlab/database.rb b/ee/lib/ee/gitlab/database.rb index 9ec5cc53f2b40535fb13a5c321933472f4f67e6f..6d72783cba9f08f77c73ea66714a725c61f35586 100644 --- a/ee/lib/ee/gitlab/database.rb +++ b/ee/lib/ee/gitlab/database.rb @@ -17,12 +17,6 @@ def healthy? !Postgresql::ReplicationSlot.lag_too_great? end - # Disables prepared statements for the current database connection. - def disable_prepared_statements - config = ::Gitlab::Database.config.merge(prepared_statements: false) - ActiveRecord::Base.establish_connection(config) - end - def geo_uncached_queries(&block) raise 'No block given' unless block_given? diff --git a/ee/lib/ee/gitlab/database/consistency.rb b/ee/lib/ee/gitlab/database/consistency.rb deleted file mode 100644 index a3ccda7526f9020dfcca8733c216bc0e8167fa64..0000000000000000000000000000000000000000 --- a/ee/lib/ee/gitlab/database/consistency.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -module EE - module Gitlab - module Database - module Consistency - extend ::Gitlab::Utils::Override - ## - # In EE we are disabling the database load balancing for calls that - # require read consistency after recent writes. - # - override :with_read_consistency - def with_read_consistency(&block) - ::Gitlab::Database::LoadBalancing::Session - .current.use_primary(&block) - end - end - end - end -end diff --git a/ee/spec/lib/ee/gitlab/database_spec.rb b/ee/spec/lib/ee/gitlab/database_spec.rb index 6c8cf098c0be332ca3dca3c496d4d5f0b0ea569d..bc2f9036b7fa3cdc4b51eab402ab3a958bdb051d 100644 --- a/ee/spec/lib/ee/gitlab/database_spec.rb +++ b/ee/spec/lib/ee/gitlab/database_spec.rb @@ -60,28 +60,6 @@ end end - describe '.disable_prepared_statements' do - around do |example| - original_config = ::Gitlab::Database.config - - example.run - - ActiveRecord::Base.establish_connection(original_config) - end - - it 'disables prepared statements' do - ActiveRecord::Base.establish_connection(::Gitlab::Database.config.merge(prepared_statements: true)) - expect(ActiveRecord::Base.connection.prepared_statements).to eq(true) - - expect(ActiveRecord::Base).to receive(:establish_connection) - .with(a_hash_including({ 'prepared_statements' => false })).and_call_original - - described_class.disable_prepared_statements - - expect(ActiveRecord::Base.connection.prepared_statements).to eq(false) - end - end - describe '.geo_uncached_queries' do context 'when no block is given' do it 'raises error' do diff --git a/ee/spec/models/ee/application_record_helpers_spec.rb b/ee/spec/models/ee/application_record_helpers_spec.rb deleted file mode 100644 index 1a2c29de5f57d36df3965f1bdd3e09e5975632c7..0000000000000000000000000000000000000000 --- a/ee/spec/models/ee/application_record_helpers_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe ApplicationRecord do - describe '.with_fast_read_statement_timeout' do - let(:session) { double(:session) } - - before do - allow(::Gitlab::Database::LoadBalancing::Session).to receive(:current).and_return(session) - allow(session).to receive(:fallback_to_replicas_for_ambiguous_queries).and_yield - end - - it 'yields control' do - expect do |blk| - described_class.with_fast_read_statement_timeout(&blk) - end.to yield_control.once - end - - context 'when the query runs faster than configured timeout' do - it 'executes the query without error' do - result = nil - - expect do - described_class.with_fast_read_statement_timeout(100) do - result = described_class.connection.exec_query('SELECT 1') - end - end.not_to raise_error - - expect(result).not_to be_nil - end - end - - # This query hangs for 10ms and then gets cancelled. As there is no - # other way to test the timeout for sure, 10ms of waiting seems to be - # reasonable! - context 'when the query runs longer than configured timeout' do - it 'cancels the query and raiss an exception' do - expect do - described_class.with_fast_read_statement_timeout(10) do - described_class.connection.exec_query('SELECT pg_sleep(0.1)') - end - end.to raise_error(ActiveRecord::QueryCanceled) - end - end - end -end diff --git a/ee/spec/tasks/geo_rake_spec.rb b/ee/spec/tasks/geo_rake_spec.rb index de6669365afee76924609a0beb3bb8aedd92bf2b..aa7e77b17dae9fcf6aa7a958eaa70bde029f4109 100644 --- a/ee/spec/tasks/geo_rake_spec.rb +++ b/ee/spec/tasks/geo_rake_spec.rb @@ -428,8 +428,7 @@ end it 'removes orphaned registries taking into account TO_PROJECT_ID' do - allow(ENV).to receive(:[]).with('FROM_PROJECT_ID').and_return(nil) - allow(ENV).to receive(:[]).with('TO_PROJECT_ID').and_return(@orphaned.project_id) + stub_env('FROM_PROJECT_ID' => nil, 'TO_PROJECT_ID' => @orphaned.project_id) run_rake_task('geo:run_orphaned_project_registry_cleaner') @@ -439,8 +438,7 @@ end it 'removes orphaned registries taking into account FROM_PROJECT_ID' do - allow(ENV).to receive(:[]).with('FROM_PROJECT_ID').and_return(@orphaned1.project_id) - allow(ENV).to receive(:[]).with('TO_PROJECT_ID').and_return(nil) + stub_env('FROM_PROJECT_ID' => @orphaned1.project_id, 'TO_PROJECT_ID' => nil) run_rake_task('geo:run_orphaned_project_registry_cleaner') diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 0305433aef469401221138b4f2a85f78c00f8edd..3583338c58a219e2b7432d038da4dcb9a680c394 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -89,6 +89,11 @@ def self.human_adapter_name end end + # Disables prepared statements for the current database connection. + def self.disable_prepared_statements + ActiveRecord::Base.establish_connection(config.merge(prepared_statements: false)) + end + # @deprecated def self.postgresql? adapter_name.casecmp('postgresql') == 0 diff --git a/lib/gitlab/database/consistency.rb b/lib/gitlab/database/consistency.rb index e99ea7a323275c20ba0604dabc21203ccc49a957..17c16640e4c95b8230977bb46cbbdb9f02df6e20 100644 --- a/lib/gitlab/database/consistency.rb +++ b/lib/gitlab/database/consistency.rb @@ -4,28 +4,18 @@ module Gitlab module Database ## # This class is used to make it possible to ensure read consistency in - # GitLab EE without the need of overriding a lot of methods / classes / + # GitLab without the need of overriding a lot of methods / classes / # classs. # - # This is a CE class that does nothing in CE, because database load - # balancing is EE-only feature, but you can still use it in CE. It will - # start ensuring read consistency once it is overridden in EE. - # - # Using this class in CE helps to avoid creeping discrepancy between CE / - # EE only to force usage of the primary database in EE. - # class Consistency ## - # In CE there is no database load balancing, so all reads are expected to - # be consistent by the ACID guarantees of a single PostgreSQL instance. - # - # This method is overridden in EE. + # Within the block, disable the database load balancing for calls that + # require read consistency after recent writes. # def self.with_read_consistency(&block) - yield + ::Gitlab::Database::LoadBalancing::Session + .current.use_primary(&block) end end end end - -::Gitlab::Database::Consistency.singleton_class.prepend_mod_with('Gitlab::Database::Consistency') diff --git a/ee/lib/gitlab/database/load_balancing.rb b/lib/gitlab/database/load_balancing.rb similarity index 85% rename from ee/lib/gitlab/database/load_balancing.rb rename to lib/gitlab/database/load_balancing.rb index 76e67e27f911900150164b19c0b246bed9e1c199..ea4628ab757f5498cc0dedcaf192ac64084146b0 100644 --- a/ee/lib/gitlab/database/load_balancing.rb +++ b/lib/gitlab/database/load_balancing.rb @@ -102,23 +102,9 @@ def self.configured? hosts.any? || service_discovery_enabled? end + # Temporarily disabled for FOSS until move from EE to FOSS is complete def self.feature_available? - # If this method is called in any subscribers listening to - # sql.active_record, the SQL call below may cause infinite recursion. - # So, the memoization variable must have 3 states - # - First call: @feature_available is undefined - # -> Set @feature_available to false - # -> Trigger SQL - # -> SQL subscriber triggers this method again - # -> return false - # -> Set @feature_available to true - # -> return true - # - Second call: return @feature_available right away - return @feature_available if defined?(@feature_available) - - @feature_available = false - @feature_available = Gitlab::Database.cached_table_exists?('licenses') && - ::License.feature_available?(:db_load_balancing) + Gitlab.ee? || Gitlab::Utils.to_boolean(ENV['ENABLE_LOAD_BALANCING_FOR_FOSS'], default: false) end def self.start_service_discovery diff --git a/ee/lib/gitlab/database/load_balancing/active_record_proxy.rb b/lib/gitlab/database/load_balancing/active_record_proxy.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/active_record_proxy.rb rename to lib/gitlab/database/load_balancing/active_record_proxy.rb diff --git a/ee/lib/gitlab/database/load_balancing/connection_proxy.rb b/lib/gitlab/database/load_balancing/connection_proxy.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/connection_proxy.rb rename to lib/gitlab/database/load_balancing/connection_proxy.rb diff --git a/ee/lib/gitlab/database/load_balancing/host.rb b/lib/gitlab/database/load_balancing/host.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/host.rb rename to lib/gitlab/database/load_balancing/host.rb diff --git a/ee/lib/gitlab/database/load_balancing/host_list.rb b/lib/gitlab/database/load_balancing/host_list.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/host_list.rb rename to lib/gitlab/database/load_balancing/host_list.rb diff --git a/ee/lib/gitlab/database/load_balancing/load_balancer.rb b/lib/gitlab/database/load_balancing/load_balancer.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/load_balancer.rb rename to lib/gitlab/database/load_balancing/load_balancer.rb diff --git a/ee/lib/gitlab/database/load_balancing/logger.rb b/lib/gitlab/database/load_balancing/logger.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/logger.rb rename to lib/gitlab/database/load_balancing/logger.rb diff --git a/ee/lib/gitlab/database/load_balancing/rack_middleware.rb b/lib/gitlab/database/load_balancing/rack_middleware.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/rack_middleware.rb rename to lib/gitlab/database/load_balancing/rack_middleware.rb diff --git a/ee/lib/gitlab/database/load_balancing/resolver.rb b/lib/gitlab/database/load_balancing/resolver.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/resolver.rb rename to lib/gitlab/database/load_balancing/resolver.rb diff --git a/ee/lib/gitlab/database/load_balancing/service_discovery.rb b/lib/gitlab/database/load_balancing/service_discovery.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/service_discovery.rb rename to lib/gitlab/database/load_balancing/service_discovery.rb diff --git a/ee/lib/gitlab/database/load_balancing/session.rb b/lib/gitlab/database/load_balancing/session.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/session.rb rename to lib/gitlab/database/load_balancing/session.rb diff --git a/ee/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb rename to lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb diff --git a/ee/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb rename to lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb diff --git a/ee/lib/gitlab/database/load_balancing/srv_resolver.rb b/lib/gitlab/database/load_balancing/srv_resolver.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/srv_resolver.rb rename to lib/gitlab/database/load_balancing/srv_resolver.rb diff --git a/ee/lib/gitlab/database/load_balancing/sticking.rb b/lib/gitlab/database/load_balancing/sticking.rb similarity index 100% rename from ee/lib/gitlab/database/load_balancing/sticking.rb rename to lib/gitlab/database/load_balancing/sticking.rb diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh index b1a618270b0961dae407023f73acbb91ffff10fc..0484cabca82e0ce1a959ac4f2ce3606ea45d0871 100644 --- a/scripts/rspec_helpers.sh +++ b/scripts/rspec_helpers.sh @@ -85,7 +85,7 @@ function rspec_db_library_code() { local db_files="spec/lib/gitlab/database/ spec/support/helpers/database/" if [[ -d "ee/" ]]; then - db_files="${db_files} ee/spec/lib/gitlab/database/ ee/spec/lib/ee/gitlab/database_spec.rb" + db_files="${db_files} ee/spec/lib/ee/gitlab/database_spec.rb" fi rspec_simple_job "-- ${db_files}" diff --git a/ee/spec/fixtures/dns/a_rr.json b/spec/fixtures/dns/a_rr.json similarity index 100% rename from ee/spec/fixtures/dns/a_rr.json rename to spec/fixtures/dns/a_rr.json diff --git a/ee/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json b/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json similarity index 100% rename from ee/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json rename to spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json diff --git a/ee/spec/fixtures/dns/aaaa_rr.json b/spec/fixtures/dns/aaaa_rr.json similarity index 100% rename from ee/spec/fixtures/dns/aaaa_rr.json rename to spec/fixtures/dns/aaaa_rr.json diff --git a/ee/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json b/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json similarity index 100% rename from ee/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json rename to spec/fixtures/dns/srv_with_a_rr_in_additional_section.json diff --git a/ee/spec/lib/gitlab/database/consistency_spec.rb b/spec/lib/gitlab/database/consistency_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/consistency_spec.rb rename to spec/lib/gitlab/database/consistency_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/active_record_proxy_spec.rb b/spec/lib/gitlab/database/load_balancing/active_record_proxy_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/active_record_proxy_spec.rb rename to spec/lib/gitlab/database/load_balancing/active_record_proxy_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb b/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb rename to spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/host_list_spec.rb b/spec/lib/gitlab/database/load_balancing/host_list_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/host_list_spec.rb rename to spec/lib/gitlab/database/load_balancing/host_list_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/host_spec.rb b/spec/lib/gitlab/database/load_balancing/host_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/host_spec.rb rename to spec/lib/gitlab/database/load_balancing/host_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb similarity index 99% rename from ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb rename to spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb index a16d77a447df18487b9e84dd990efabee57341f5..59f7016538053d05d16522eea1822d97c6914f75 100644 --- a/ee/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb @@ -294,7 +294,7 @@ def twice_wrapped_exception(top, middle, original) describe '#primary_write_location' do it 'returns a String in the right format' do - expect(lb.primary_write_location).to match(/[A-F0-9]{1,8}\/[A-F0-9]{1,8}/) + expect(lb.primary_write_location).to match(%r{[A-F0-9]{1,8}/[A-F0-9]{1,8}}) end it 'raises an error if the write location could not be retrieved' do diff --git a/ee/spec/lib/gitlab/database/load_balancing/rack_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/rack_middleware_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/rack_middleware_spec.rb rename to spec/lib/gitlab/database/load_balancing/rack_middleware_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/resolver_spec.rb b/spec/lib/gitlab/database/load_balancing/resolver_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/resolver_spec.rb rename to spec/lib/gitlab/database/load_balancing/resolver_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb b/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb rename to spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/session_spec.rb b/spec/lib/gitlab/database/load_balancing/session_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/session_spec.rb rename to spec/lib/gitlab/database/load_balancing/session_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb rename to spec/lib/gitlab/database/load_balancing/sidekiq_client_middleware_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb rename to spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb b/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb similarity index 95% rename from ee/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb rename to spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb index 029dc426516db31c56518b23deb2f64af98e91eb..6ac0608d4851de8bc46072513861c4c2939fb589 100644 --- a/ee/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb @@ -52,7 +52,7 @@ end def dns_response_packet_from_fixture(fixture_name) - fixture = File.read(Rails.root + "ee/spec/fixtures/dns/#{fixture_name}.json") + fixture = File.read(Rails.root + "spec/fixtures/dns/#{fixture_name}.json") encoded_payload = Gitlab::Json.parse(fixture)['payload'] payload = Base64.decode64(encoded_payload) diff --git a/ee/spec/lib/gitlab/database/load_balancing/sticking_spec.rb b/spec/lib/gitlab/database/load_balancing/sticking_spec.rb similarity index 100% rename from ee/spec/lib/gitlab/database/load_balancing/sticking_spec.rb rename to spec/lib/gitlab/database/load_balancing/sticking_spec.rb diff --git a/ee/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb similarity index 96% rename from ee/spec/lib/gitlab/database/load_balancing_spec.rb rename to spec/lib/gitlab/database/load_balancing_spec.rb index fc318be42aa5e4bff077d3cfd857656839901292..c3dcfa3eb4a542778d5b4a3263fd2997c6fcdd28 100644 --- a/ee/spec/lib/gitlab/database/load_balancing_spec.rb +++ b/spec/lib/gitlab/database/load_balancing_spec.rb @@ -5,6 +5,10 @@ RSpec.describe Gitlab::Database::LoadBalancing do include_context 'clear DB Load Balancing configuration' + before do + stub_env('ENABLE_LOAD_BALANCING_FOR_FOSS', 'true') + end + describe '.proxy' do context 'when configured' do before do @@ -127,8 +131,6 @@ end describe '.enable?' do - let!(:license) { create(:license, plan: ::License::PREMIUM_PLAN) } - before do clear_load_balancing_configuration allow(described_class).to receive(:hosts).and_return(%w(foo)) @@ -181,27 +183,22 @@ end end - context 'without a license' do + context 'FOSS' do before do - License.destroy_all # rubocop: disable Cop/DestroyAll - clear_load_balancing_configuration - end + allow(Gitlab).to receive(:ee?).and_return(false) - it 'is disabled' do - expect(described_class.enable?).to eq(false) + stub_env('ENABLE_LOAD_BALANCING_FOR_FOSS', 'false') end - end - - context 'with an EES license' do - let!(:license) { create(:license, plan: ::License::STARTER_PLAN) } it 'is disabled' do expect(described_class.enable?).to eq(false) end end - context 'with an EEP license' do - let!(:license) { create(:license, plan: ::License::PREMIUM_PLAN) } + context 'EE' do + before do + allow(Gitlab).to receive(:ee?).and_return(true) + end it 'is enabled' do allow(described_class).to receive(:hosts).and_return(%w(foo)) @@ -213,8 +210,6 @@ end describe '.configured?' do - let!(:license) { create(:license, plan: ::License::PREMIUM_PLAN) } - before do clear_load_balancing_configuration end @@ -245,17 +240,6 @@ expect(described_class.configured?).to eq(false) end - - context 'without a license' do - before do - License.destroy_all # rubocop: disable Cop/DestroyAll - clear_load_balancing_configuration - end - - it 'is not configured' do - expect(described_class.configured?).to eq(false) - end - end end describe '.configure_proxy' do @@ -444,7 +428,6 @@ end before do - stub_licensed_features(db_load_balancing: true) # Preloading testing class model.singleton_class.prepend ::Gitlab::Database::LoadBalancing::ActiveRecordProxy diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 663c8d69328b4ca18964e3b3743995a2cfe53f95..2b31f3b4dee19e53d8d62c53315781f5052fbe34 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -65,6 +65,28 @@ end end + describe '.disable_prepared_statements' do + around do |example| + original_config = ::Gitlab::Database.config + + example.run + + ActiveRecord::Base.establish_connection(original_config) + end + + it 'disables prepared statements' do + ActiveRecord::Base.establish_connection(::Gitlab::Database.config.merge(prepared_statements: true)) + expect(ActiveRecord::Base.connection.prepared_statements).to eq(true) + + expect(ActiveRecord::Base).to receive(:establish_connection) + .with(a_hash_including({ 'prepared_statements' => false })).and_call_original + + described_class.disable_prepared_statements + + expect(ActiveRecord::Base.connection.prepared_statements).to eq(false) + end + end + describe '.postgresql?' do subject { described_class.postgresql? } diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb index 24de46cb536c969a148941bd42acc5d5224f9193..85a6717d259b87227b57f7038f896d88daf8898c 100644 --- a/spec/models/application_record_spec.rb +++ b/spec/models/application_record_spec.rb @@ -132,5 +132,47 @@ end.to raise_error(ActiveRecord::QueryCanceled) end end + + context 'with database load balancing' do + let(:session) { double(:session) } + + before do + allow(::Gitlab::Database::LoadBalancing::Session).to receive(:current).and_return(session) + allow(session).to receive(:fallback_to_replicas_for_ambiguous_queries).and_yield + end + + it 'yields control' do + expect do |blk| + described_class.with_fast_read_statement_timeout(&blk) + end.to yield_control.once + end + + context 'when the query runs faster than configured timeout' do + it 'executes the query without error' do + result = nil + + expect do + described_class.with_fast_read_statement_timeout(100) do + result = described_class.connection.exec_query('SELECT 1') + end + end.not_to raise_error + + expect(result).not_to be_nil + end + end + + # This query hangs for 10ms and then gets cancelled. As there is no + # other way to test the timeout for sure, 10ms of waiting seems to be + # reasonable! + context 'when the query runs longer than configured timeout' do + it 'cancels the query and raiss an exception' do + expect do + described_class.with_fast_read_statement_timeout(10) do + described_class.connection.exec_query('SELECT pg_sleep(0.1)') + end + end.to raise_error(ActiveRecord::QueryCanceled) + end + end + end end end diff --git a/ee/spec/support/shared_contexts/load_balancing_configuration_shared_context.rb b/spec/support/shared_contexts/load_balancing_configuration_shared_context.rb similarity index 100% rename from ee/spec/support/shared_contexts/load_balancing_configuration_shared_context.rb rename to spec/support/shared_contexts/load_balancing_configuration_shared_context.rb