From 8f5373ced143de97eaf1c8a4786e267e926f3445 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Thu, 22 May 2025 10:32:54 -0500 Subject: [PATCH 01/31] Update to rails 7.1 in load balancing gem --- .../Gemfile.lock | 270 +++++++++++------- .../gitlab-database-load_balancing.gemspec | 10 +- 2 files changed, 173 insertions(+), 107 deletions(-) diff --git a/gems/gitlab-database-load_balancing/Gemfile.lock b/gems/gitlab-database-load_balancing/Gemfile.lock index 6fe6df1c82e89d..94a48f369e39f5 100644 --- a/gems/gitlab-database-load_balancing/Gemfile.lock +++ b/gems/gitlab-database-load_balancing/Gemfile.lock @@ -32,92 +32,111 @@ PATH remote: . specs: gitlab-database-load_balancing (0.1.0) - gitlab-net-dns (~> 0.9.2) - pg (~> 1.5.4) - rails (>= 7) + gitlab-net-dns (~> 0.12) + pg (~> 1.5.6) + rails (>= 7.1, < 7.2) GEM remote: https://rubygems.org/ specs: - actioncable (7.0.8.7) - actionpack (= 7.0.8.7) - activesupport (= 7.0.8.7) + actioncable (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8.7) - actionpack (= 7.0.8.7) - activejob (= 7.0.8.7) - activerecord (= 7.0.8.7) - activestorage (= 7.0.8.7) - activesupport (= 7.0.8.7) + zeitwerk (~> 2.6) + actionmailbox (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8.7) - actionpack (= 7.0.8.7) - actionview (= 7.0.8.7) - activejob (= 7.0.8.7) - activesupport (= 7.0.8.7) + actionmailer (7.1.5.1) + actionpack (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activesupport (= 7.1.5.1) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp - rails-dom-testing (~> 2.0) - actionpack (7.0.8.7) - actionview (= 7.0.8.7) - activesupport (= 7.0.8.7) - rack (~> 2.0, >= 2.2.4) + rails-dom-testing (~> 2.2) + actionpack (7.1.5.1) + actionview (= 7.1.5.1) + activesupport (= 7.1.5.1) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.8.7) - actionpack (= 7.0.8.7) - activerecord (= 7.0.8.7) - activestorage (= 7.0.8.7) - activesupport (= 7.0.8.7) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.5.1) + actionpack (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8.7) - activesupport (= 7.0.8.7) + actionview (7.1.5.1) + activesupport (= 7.1.5.1) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.8.7) - activesupport (= 7.0.8.7) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.5.1) + activesupport (= 7.1.5.1) globalid (>= 0.3.6) - activemodel (7.0.8.7) - activesupport (= 7.0.8.7) - activerecord (7.0.8.7) - activemodel (= 7.0.8.7) - activesupport (= 7.0.8.7) - activestorage (7.0.8.7) - actionpack (= 7.0.8.7) - activejob (= 7.0.8.7) - activerecord (= 7.0.8.7) - activesupport (= 7.0.8.7) + activemodel (7.1.5.1) + activesupport (= 7.1.5.1) + activerecord (7.1.5.1) + activemodel (= 7.1.5.1) + activesupport (= 7.1.5.1) + timeout (>= 0.4.0) + activestorage (7.1.5.1) + actionpack (= 7.1.5.1) + activejob (= 7.1.5.1) + activerecord (= 7.1.5.1) + activesupport (= 7.1.5.1) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (7.0.8.7) + activesupport (7.1.5.1) + base64 + benchmark (>= 0.3) + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) builder (3.2.4) coderay (1.1.3) concurrent-ruby (1.2.2) + connection_pool (2.5.3) crass (1.0.6) date (3.3.3) debug_inspector (1.1.0) diff-lcs (1.5.0) + drb (2.2.3) + erb (5.0.2) erubi (1.12.0) - gitlab-net-dns (0.9.2) + gitlab-net-dns (0.15.0) + logger gitlab-styles (10.1.0) rubocop (~> 1.50.2) rubocop-graphql (~> 0.18) @@ -128,7 +147,13 @@ GEM activesupport (>= 6.1) i18n (1.12.0) concurrent-ruby (~> 1.0) + io-console (0.8.1) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) json (2.6.3) + logger (1.7.0) loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -142,6 +167,7 @@ GEM mini_mime (1.1.5) mini_portile2 (2.8.7) minitest (5.17.0) + mutex_m (0.3.0) net-imap (0.4.4) date net-protocol @@ -171,7 +197,10 @@ GEM parser (3.2.2.3) ast (~> 2.4.1) racc - pg (1.5.4) + pg (1.5.9) + pp (0.6.2) + prettyprint + prettyprint (0.2.0) proc_to_ast (0.1.0) coderay parser @@ -179,25 +208,33 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) + psych (5.2.6) + date + stringio public_suffix (5.0.3) racc (1.8.1) rack (2.2.17) + rack-session (1.0.2) + rack (< 3) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8.7) - actioncable (= 7.0.8.7) - actionmailbox (= 7.0.8.7) - actionmailer (= 7.0.8.7) - actionpack (= 7.0.8.7) - actiontext (= 7.0.8.7) - actionview (= 7.0.8.7) - activejob (= 7.0.8.7) - activemodel (= 7.0.8.7) - activerecord (= 7.0.8.7) - activestorage (= 7.0.8.7) - activesupport (= 7.0.8.7) + rackup (1.0.1) + rack (< 3) + webrick + rails (7.1.5.1) + actioncable (= 7.1.5.1) + actionmailbox (= 7.1.5.1) + actionmailer (= 7.1.5.1) + actionpack (= 7.1.5.1) + actiontext (= 7.1.5.1) + actionview (= 7.1.5.1) + activejob (= 7.1.5.1) + activemodel (= 7.1.5.1) + activerecord (= 7.1.5.1) + activestorage (= 7.1.5.1) + activesupport (= 7.1.5.1) bundler (>= 1.15.0) - railties (= 7.0.8.7) + railties (= 7.1.5.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -205,31 +242,37 @@ GEM rails-html-sanitizer (1.6.1) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.0.8.7) - actionpack (= 7.0.8.7) - activesupport (= 7.0.8.7) - method_source + railties (7.1.5.1) + actionpack (= 7.1.5.1) + activesupport (= 7.1.5.1) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - zeitwerk (~> 2.5) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.1.0) + rdoc (6.14.2) + erb + psych (>= 4.0.0) regexp_parser (2.7.0) + reline (0.6.2) + io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) rexml (3.3.9) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.1) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.2) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.3) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) + rspec-support (~> 3.13.0) rspec-parameterized (1.0.0) rspec-parameterized-core (< 2) rspec-parameterized-table_syntax (< 2) @@ -249,7 +292,7 @@ GEM rspec-expectations (~> 3.12) rspec-mocks (~> 3.12) rspec-support (~> 3.12) - rspec-support (3.12.0) + rspec-support (3.13.4) rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) @@ -280,6 +323,8 @@ GEM rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) ruby-progressbar (1.11.0) + securerandom (0.4.1) + stringio (3.1.7) thor (1.3.0) timeout (0.4.0) tzinfo (2.0.6) @@ -288,6 +333,7 @@ GEM unparser (0.6.8) diff-lcs (~> 1.3) parser (>= 3.2.0) + webrick (1.9.1) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -309,47 +355,56 @@ DEPENDENCIES gitlab-safe_request_store! gitlab-styles (~> 10.1.0) gitlab-utils! - pg (~> 1.5.4) + pg (~> 1.5.6) pry - rspec (~> 3.0) + rspec (~> 3.13) rspec-parameterized (~> 1.0) rspec-rails (~> 6.0.1) rubocop (~> 1.50) rubocop-rspec (~> 2.22) CHECKSUMS - actioncable (7.0.8.7) sha256=4034513841df2fd09dbbf38f37c1a00fc6c841122a8714e5d6916b8d6ce2f162 - actionmailbox (7.0.8.7) sha256=940eeaa3d8e85dcd9fc6069e39571e13c5a4bdb0db52c7ab96d14da81d6ac1c2 - actionmailer (7.0.8.7) sha256=8be8f9a2f8774af89822bc92e1ab6df10b3a2be59c75486a34e86a1f10d88d14 - actionpack (7.0.8.7) sha256=40e6b1d687904a4fd2285d1fa3aad3d9a9d9ba8fd8858dd0faa9f4673c3f5e2c - actiontext (7.0.8.7) sha256=cb75d2db97d5b2c8caccdc0f643541df36c2c53f076a2d49b226f971d8d528a0 - actionview (7.0.8.7) sha256=be975bc9c61903fe5da80a97c345271159033bcbba63988c7f27b6b8b98f7fed - activejob (7.0.8.7) sha256=eff4db3aeaee34863a47570089d11d5577ed0ea42b1475dc9be6a413be182a20 - activemodel (7.0.8.7) sha256=f13b04bb055c1e85b965ce40b0a2e671b8d97835083597bc7fbc04cde0f40a83 - activerecord (7.0.8.7) sha256=f94fc8510e58a18e462c5ee8862c9be75e2bfad0688e8d022b86a6e05df2a45a + actioncable (7.1.5.1) sha256=764637b5b2d97b94e412d562c177bfd16b0fd769d55c98846362f5263e8aaa0d + actionmailbox (7.1.5.1) sha256=c3c20589fe43e6fa88bba2d76a6f9805ffdd02531f4a9a4af8197d59f5a5360a + actionmailer (7.1.5.1) sha256=b213d6d880b23b093ccfef3b4f87a3d27e4666442f71b5b634b2d19e19a49759 + actionpack (7.1.5.1) sha256=2bc263d9f43f16cc3b3360f59659ab11f140577602f371f1a968e2672b38d718 + actiontext (7.1.5.1) sha256=b8e261cfad5bc6a78b3f15be5e7c7f32190041b3dc6f027a3a353b4392d2f7ec + actionview (7.1.5.1) sha256=8c559a213501798e29b50b5341a643a70bbf6fa0aa2abaf571d0efc59dc4f6aa + activejob (7.1.5.1) sha256=7633376c857f4c491d06b5a7f5d86d9f07afc595398354a3f1abe80eb7e35767 + activemodel (7.1.5.1) sha256=74727466854a7fbdfe8f2702ca3112b23877500d4926bf7e02e921ad542191f1 + activerecord (7.1.5.1) sha256=f40ad1609bf33b9ba5bdc4e16d80a77b1517153234ceb413d31d635d7b91f1e3 activerecord-gitlab (0.2.0) - activestorage (7.0.8.7) sha256=ca411e73733a50983f44b0945bfd0612313beb3a8f914cd3a88e4fcd99399ef5 - activesupport (7.0.8.7) sha256=df4702375de924aae81709c831605317c5417f0bd9e502a0373ff84a067204ff + activestorage (7.1.5.1) sha256=ae6b8b076858c666eaad6f896d786b67654235e861e24a83f61f1cc97b43ff63 + activesupport (7.1.5.1) sha256=9f0c482e473b9868cb3dfe3e9db549a3bd2302c02e4f595a5caac144a8c7cfb8 addressable (2.8.5) sha256=63f0fbcde42edf116d6da98a9437f19dd1692152f1efa3fcc4741e443c772117 ast (2.4.2) sha256=1e280232e6a33754cde542bc5ef85520b74db2aac73ec14acef453784447cc12 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + benchmark (0.4.1) sha256=d4ef40037bba27f03b28013e219b950b82bace296549ec15a78016552f8d2cce + bigdecimal (3.2.2) sha256=39085f76b495eb39a79ce07af716f3a6829bc35eb44f2195e2753749f2fa5adc binding_of_caller (1.0.0) sha256=3aad25d1d538fc6e7972978f9bf512ccd992784009947c81633bea776713161d builder (3.2.4) sha256=99caf08af60c8d7f3a6b004029c4c3c0bdaebced6c949165fe98f1db27fbbc10 coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b concurrent-ruby (1.2.2) sha256=3879119b8b75e3b62616acc256c64a134d0b0a7a9a3fcba5a233025bcde22c4f + connection_pool (2.5.3) sha256=cfd74a82b9b094d1ce30c4f1a346da23ee19dc8a062a16a85f58eab1ced4305b crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d date (3.3.3) sha256=819792019d5712b748fb15f6dfaaedef14b0328723ef23583ea35f186774530f debug_inspector (1.1.0) sha256=eaa5a2d0195e1d65fb4164e8e7e466cca2e7eb53bc5e608cf12b8bf02c3a8606 diff-lcs (1.5.0) sha256=49b934001c8c6aedb37ba19daec5c634da27b318a7a3c654ae979d6ba1929b67 + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + erb (5.0.2) sha256=d30f258143d4300fb4ecf430042ac12970c9bb4b33c974a545b8f58c1ec26c0f erubi (1.12.0) sha256=27bedb74dfb1e04ff60674975e182d8ca787f2224f2e8143268c7696f42e4723 gitlab-database-load_balancing (0.1.0) - gitlab-net-dns (0.9.2) sha256=f726d978479d43810819f12a45c0906d775a07e34df111bbe693fffbbef3059d + gitlab-net-dns (0.15.0) sha256=d229aae205055b86b2ad166981257eb589ce6d6a146aa79b3ea2b1e5d9741f46 gitlab-rspec (0.1.0) gitlab-safe_request_store (0.1.0) gitlab-styles (10.1.0) sha256=f42745f5397d042fe24cf2d0eb56c995b37f9f43d8fb79b834d197a1cafdc84a gitlab-utils (0.1.0) globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9 i18n (1.12.0) sha256=91e3cc1b97616d308707eedee413d82ee021d751c918661fb82152793e64aced + io-console (0.8.1) sha256=1e15440a6b2f67b6ea496df7c474ed62c860ad11237f29b3bd187f054b925fcb + irb (1.15.2) sha256=222f32952e278da34b58ffe45e8634bf4afc2dc7aa9da23fed67e581aa50fdba json (2.6.3) sha256=86aaea16adf346a2b22743d88f8dcceeb1038843989ab93cda44b5176c845459 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 loofah (2.21.4) sha256=2c18cd5db9fd92a48a270344e57a5b84cf22d668b78e1481f10e4f2cde4eb734 mail (2.8.1) sha256=ec3b9fadcf2b3755c78785cb17bc9a0ca9ee9857108a64b6f5cfc9c0b5bfc9ad marcel (1.0.2) sha256=a013b677ef46cbcb49fd5c59b3d35803d2ee04dd75d8bfdc43533fc5a31f7e4e @@ -357,6 +412,7 @@ CHECKSUMS mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef mini_portile2 (2.8.7) sha256=13eef5ab459bbfd33d61e539564ec25a9c2cf593b0a5ea6d4d7ef8c19b162ee0 minitest (5.17.0) sha256=c0dfaa3e99ed5ee3500c92bb114cf9d0d3c1e6995e162dd7b49970a9f0315ece + mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 net-imap (0.4.4) sha256=7e61f6260343db3b49cee914f411aae81bc3ea768938112e805f9c329b59bce7 net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.1) sha256=21adb19c197768899c389bd257545de9d5af64adb1928787653460c2699eac37 @@ -371,31 +427,38 @@ CHECKSUMS nokogiri (1.16.8-x86_64-linux) sha256=ed7b1f80713ac968dd93fe2b96fc3df6e448b73bd02dd77d5fc89ba92a1ed6d9 parallel (1.22.1) sha256=ebdf1f0c51f182df38522f70ba770214940bef998cdb6e00f36492b29699761f parser (3.2.2.3) sha256=10685f358ab36ffea2252dc4952e5b8fad3a297a8152a85f59adc982747b91eb - pg (1.5.4) sha256=04f7b247151c639a0b955d8e5a9a41541343f4640aa3c2bdf749a872c339d25d + pg (1.5.9) sha256=761efbdf73b66516f0c26fcbe6515dc7500c3f0aa1a1b853feae245433c64fdc + pp (0.6.2) sha256=947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 proc_to_ast (0.1.0) sha256=92a73fa66e2250a83f8589f818b0751bcf227c68f85916202df7af85082f8691 pry (0.14.2) sha256=c4fe54efedaca1d351280b45b8849af363184696fcac1c72e0415f9bdac4334d + psych (5.2.6) sha256=814328aa5dcb6d604d32126a20bc1cbcf05521a5b49dbb1a8b30a07e580f316e public_suffix (5.0.3) sha256=337d475da2bd2ea1de0446751cb972ad43243b4b00aa8cf91cb904fa593d3259 racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f rack (2.2.17) sha256=5fe02a1ca80d6fb2271dba00985ee2962d6f5620b6f46dfed89f5301ac4699dd + rack-session (1.0.2) sha256=a02115e5420b4de036839b9811e3f7967d73446a554b42aa45106af335851d76 rack-test (2.1.0) sha256=0c61fc61904049d691922ea4bb99e28004ed3f43aa5cfd495024cc345f125dfb - rails (7.0.8.7) sha256=5e67ed4dd915746349bfb8c7ae2f531d3a36eb68fbe2f60ede02a0500715cded + rackup (1.0.1) sha256=ba86604a28989fe1043bff20d819b360944ca08156406812dca6742b24b3c249 + rails (7.1.5.1) sha256=05aea2ed7b6392b41ce0fc11455de118455025a431b6ea334a7ac2b101608804 rails-dom-testing (2.2.0) sha256=e515712e48df1f687a1d7c380fd7b07b8558faa26464474da64183a7426fa93b rails-html-sanitizer (1.6.1) sha256=e3d2fb10339f03b802e39c7f6cac28c54fd404d3f65ae39c31cca9d150c5cbf0 - railties (7.0.8.7) sha256=1ab985280b02bc4b176d36e1011148db600b763c646e3de88c02a665d864505f + railties (7.1.5.1) sha256=0be15562e2ded4efdc1b6c30f884b6d838c9ba49573dde042334b752b043e2fb rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.1.0) sha256=be6a3e1aa7f66e6c65fa57555234eb75ce4cf4ada077658449207205474199c6 + rdoc (6.14.2) sha256=9fdd44df130f856ae70cc9a264dfd659b9b40de369b16581f4ab746e42439226 regexp_parser (2.7.0) sha256=f8b8b7f34cc53c907fad6aec2b9da996a4311a0ddd92f3bfd3b999de5420c234 + reline (0.6.2) sha256=1dad26a6008872d59c8e05244b119347c9f2ddaf4a53dce97856cd5f30a02846 request_store (1.5.1) sha256=07a204d161590789f2b1d27f9f0eadcdecd6d868cb2f03240250e1bc747df78e rexml (3.3.9) sha256=d71875b85299f341edf47d44df0212e7658cbdf35aeb69cefdb63f57af3137c9 - rspec (3.12.0) sha256=ccc41799a43509dc0be84070e3f0410ac95cbd480ae7b6c245543eb64162399c - rspec-core (3.12.1) sha256=2e40c265f71eeb7caa4cac57106a715d2cd9caddc550bd9a4e632f4a372b4435 - rspec-expectations (3.12.2) sha256=8652db70b25ae3378b7274477a906b6ad1833a7b7cfbb001a03f49dd1c1d6a0d - rspec-mocks (3.12.3) sha256=cc0a1176707e641a2c66c71fe769486fec57d7df8ec7e34320f8957a1363026b + rspec (3.13.1) sha256=b9f9a58fa915b8d94a1d6b3195fe6dd28c4c34836a6097015142c4a9ace72140 + rspec-core (3.13.5) sha256=ab3f682897c6131c67f9a17cfee5022a597f283aebe654d329a565f9937a4fa3 + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.5) sha256=e4338a6f285ada9fe56f5893f5457783af8194f5d08884d17a87321d5195ea81 rspec-parameterized (1.0.0) sha256=9c07b043c72afbd23dd9a1dd48c06f46bc2fb1a6d875c6703e254932ba28b386 rspec-parameterized-core (1.0.0) sha256=287b494985e79821160af63aba4f91db8dbfa9a21cb200db34ba38f40e16ccc1 rspec-parameterized-table_syntax (1.0.1) sha256=ffead8f21f0711b3cdf8b74386f2ef7ac93b39c40b60658a5eda97072580f2fc rspec-rails (6.0.3) sha256=6d1812cfaf18dba5a08d7e30c85149b24a220fae064853a96e451376be6fd820 - rspec-support (3.12.0) sha256=dd4d44b247ff679b95b5607ac5641d197a5f9b1d33f916123cb98fc5f917c58b + rspec-support (3.13.4) sha256=184b1814f6a968102b57df631892c7f1990a91c9a3b9e80ef892a0fc2a71a3f7 rubocop (1.50.2) sha256=7cfeb0616f686ac61d049beae89f31446792d7e9f5728152657548f70aa78650 rubocop-ast (1.29.0) sha256=d1da2ab279a074baefc81758ac430c5768a8da8c7438dd4e5819ce5984d00ba1 rubocop-capybara (2.18.0) sha256=66b256755101f76dc455ba9694e2414bc957db5200401d204b00bc835401d605 @@ -405,11 +468,14 @@ CHECKSUMS rubocop-rails (2.20.2) sha256=d20cbd613900fa22bcf85a7fba78ab68b21fc4f90b1e73c97284d40674332417 rubocop-rspec (2.22.0) sha256=2d7493222c81c78ad304ddd81aaf64b3543bcfac6d3d8706c220331921753a03 ruby-progressbar (1.11.0) sha256=cc127db3866dc414ffccbf92928a241e585b3aa2b758a5563e74a6ee0f57d50a + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + stringio (3.1.7) sha256=5b78b7cb242a315fb4fca61a8255d62ec438f58da2b90be66048546ade4507fa thor (1.3.0) sha256=1adc7f9e5b3655a68c71393fee8bd0ad088d14ee8e83a0b73726f23cbb3ca7c3 timeout (0.4.0) sha256=cd6d1f3e83594a90ac1f3de8235399bff87112d97fec928ee2b77de240dd2cb5 tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b unicode-display_width (2.4.2) sha256=6a10205d1a19ca790c4e53064ba93f09d9eb234bf6bd135d9deb6001c21428be unparser (0.6.8) sha256=38262636be6aed919586eca4334140eb08c06bc5978e66e4693103384733c13c + webrick (1.9.1) sha256=b42d3c94f166f3fb73d87e9b359def9b5836c426fc8beacf38f2184a21b2a989 websocket-driver (0.7.6) sha256=f69400be7bc197879726ad8e6f5869a61823147372fd8928836a53c2c741d0db websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 zeitwerk (2.6.12) sha256=561e12975d0332fd3b62cc859aff3bab432e5f320689c8a10cd4674b5c0439be diff --git a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec index aefcf205b4a76a..1e6bb8ddb850a3 100644 --- a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec +++ b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec @@ -16,14 +16,14 @@ Gem::Specification.new do |spec| spec.files = Dir['lib/**/*.rb'] spec.require_paths = ["lib"] - spec.add_runtime_dependency 'gitlab-net-dns', '~> 0.9.2' - spec.add_runtime_dependency "pg", '~> 1.5.4' - spec.add_runtime_dependency 'rails', '>= 7' + spec.add_runtime_dependency 'gitlab-net-dns', '~> 0.12' + spec.add_runtime_dependency "pg", '~> 1.5.6' + spec.add_runtime_dependency 'rails', '>= 7.1', '< 7.2' spec.add_development_dependency "gitlab-styles", "~> 10.1.0" - spec.add_development_dependency "pg", '~> 1.5.4' + spec.add_development_dependency "pg", '~> 1.5.6' spec.add_development_dependency "pry" - spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "rspec", "~> 3.13" spec.add_development_dependency "rspec-parameterized", "~> 1.0" spec.add_development_dependency "rspec-rails", "~> 6.0.1" spec.add_development_dependency "rubocop", "~> 1.50" -- GitLab From ba366a2d22cad1d3f0be92f3ca05cc5d8848465e Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 16 Jul 2025 10:57:14 -0500 Subject: [PATCH 02/31] Test load balancer gem against rails-next Adds a Gemfile.next for the load balancer gem, pointing to rails 7.2. Mirror the logic in base .gitlab-ci.yml to only run rails-next load balancer testing in rails next pipelines. This way the standard pipelines can pass while the load balancer isn't yet rails-next compatible. --- .../.gitlab-ci.yml | 10 + gems/gitlab-database-load_balancing/Gemfile | 10 + .../Gemfile.lock | 3 +- .../Gemfile.next | 1 + .../Gemfile.next.lock | 353 ++++++++++++++++++ .../gitlab-database-load_balancing.gemspec | 2 +- 6 files changed, 377 insertions(+), 2 deletions(-) create mode 120000 gems/gitlab-database-load_balancing/Gemfile.next create mode 100644 gems/gitlab-database-load_balancing/Gemfile.next.lock diff --git a/gems/gitlab-database-load_balancing/.gitlab-ci.yml b/gems/gitlab-database-load_balancing/.gitlab-ci.yml index 6816d641291d6d..c798e8d2e5b2b4 100644 --- a/gems/gitlab-database-load_balancing/.gitlab-ci.yml +++ b/gems/gitlab-database-load_balancing/.gitlab-ci.yml @@ -2,3 +2,13 @@ include: - local: gems/gem-pg.gitlab-ci.yml inputs: gem_name: "gitlab-database-load_balancing" + +variables: + BUNDLE_GEMFILE: 'Gemfile' + +workflow: + rules: + - if: '$CI_COMMIT_BRANCH == "rails-next" || $CI_MERGE_REQUEST_LABELS =~ /pipeline:run-with-rails-next/' + variables: + BUNDLE_GEMFILE: 'Gemfile.next' + - when: always diff --git a/gems/gitlab-database-load_balancing/Gemfile b/gems/gitlab-database-load_balancing/Gemfile index 05b508b1333f60..8e1f07650a181f 100644 --- a/gems/gitlab-database-load_balancing/Gemfile +++ b/gems/gitlab-database-load_balancing/Gemfile @@ -1,5 +1,9 @@ # frozen_string_literal: true +def next? + File.basename(__FILE__) == "Gemfile.next" +end + source "https://rubygems.org" # Specify your gem's dependencies in gitlab-safe_request_store.gemspec @@ -12,3 +16,9 @@ end gem 'activerecord-gitlab', path: '../activerecord-gitlab' gem 'gitlab-utils', path: '../gitlab-utils' gem 'gitlab-safe_request_store', path: '../gitlab-safe_request_store' + +if next? + gem 'rails', '~> 7.2' +else + gem 'rails', '~> 7.1.5.1' +end diff --git a/gems/gitlab-database-load_balancing/Gemfile.lock b/gems/gitlab-database-load_balancing/Gemfile.lock index 94a48f369e39f5..e3bddf09d7221a 100644 --- a/gems/gitlab-database-load_balancing/Gemfile.lock +++ b/gems/gitlab-database-load_balancing/Gemfile.lock @@ -34,7 +34,7 @@ PATH gitlab-database-load_balancing (0.1.0) gitlab-net-dns (~> 0.12) pg (~> 1.5.6) - rails (>= 7.1, < 7.2) + rails (>= 7.1) GEM remote: https://rubygems.org/ @@ -357,6 +357,7 @@ DEPENDENCIES gitlab-utils! pg (~> 1.5.6) pry + rails (~> 7.1.5.1) rspec (~> 3.13) rspec-parameterized (~> 1.0) rspec-rails (~> 6.0.1) diff --git a/gems/gitlab-database-load_balancing/Gemfile.next b/gems/gitlab-database-load_balancing/Gemfile.next new file mode 120000 index 00000000000000..6ab79009c0a374 --- /dev/null +++ b/gems/gitlab-database-load_balancing/Gemfile.next @@ -0,0 +1 @@ +Gemfile \ No newline at end of file diff --git a/gems/gitlab-database-load_balancing/Gemfile.next.lock b/gems/gitlab-database-load_balancing/Gemfile.next.lock new file mode 100644 index 00000000000000..e108c018302098 --- /dev/null +++ b/gems/gitlab-database-load_balancing/Gemfile.next.lock @@ -0,0 +1,353 @@ +PATH + remote: ../activerecord-gitlab + specs: + activerecord-gitlab (0.2.0) + activerecord (>= 7) + +PATH + remote: ../gitlab-rspec + specs: + gitlab-rspec (0.1.0) + activerecord (>= 6.1, < 8) + activesupport (>= 6.1, < 8) + rspec (~> 3.0) + +PATH + remote: ../gitlab-safe_request_store + specs: + gitlab-safe_request_store (0.1.0) + rack (~> 2.2.8) + request_store + +PATH + remote: ../gitlab-utils + specs: + gitlab-utils (0.1.0) + actionview (>= 6.1.7.2) + activesupport (>= 6.1.7.2) + addressable (~> 2.8) + rake (~> 13.0) + +PATH + remote: . + specs: + gitlab-database-load_balancing (0.1.0) + gitlab-net-dns (~> 0.12) + pg (~> 1.5.6) + rails (>= 7.1) + +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) + mail (>= 2.8.0) + actionmailer (7.2.2.1) + actionpack (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activesupport (= 7.2.2.1) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (7.2.2.1) + actionview (= 7.2.2.1) + activesupport (= 7.2.2.1) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4, < 3.2) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (7.2.2.1) + actionpack (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.2.2.1) + activesupport (= 7.2.2.1) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.2.2.1) + activesupport (= 7.2.2.1) + globalid (>= 0.3.6) + activemodel (7.2.2.1) + activesupport (= 7.2.2.1) + activerecord (7.2.2.1) + activemodel (= 7.2.2.1) + activesupport (= 7.2.2.1) + timeout (>= 0.4.0) + activestorage (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activesupport (= 7.2.2.1) + marcel (~> 1.0) + activesupport (7.2.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + ast (2.4.3) + base64 (0.3.0) + benchmark (0.4.1) + bigdecimal (3.2.2) + binding_of_caller (1.0.1) + debug_inspector (>= 1.2.0) + builder (3.3.0) + coderay (1.1.3) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + crass (1.0.6) + date (3.4.1) + debug_inspector (1.2.0) + diff-lcs (1.6.2) + drb (2.2.3) + erb (5.0.2) + erubi (1.13.1) + gitlab-net-dns (0.15.0) + logger + gitlab-styles (10.1.0) + rubocop (~> 1.50.2) + rubocop-graphql (~> 0.18) + rubocop-performance (~> 1.15) + rubocop-rails (~> 2.17) + rubocop-rspec (~> 2.22) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + io-console (0.8.1) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + json (2.12.2) + logger (1.7.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.4) + method_source (1.1.0) + mini_mime (1.1.5) + mini_portile2 (2.8.9) + minitest (5.25.5) + net-imap (0.5.9) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.4) + nokogiri (1.18.8) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + parallel (1.27.0) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + pg (1.5.9) + pp (0.6.2) + prettyprint + prettyprint (0.2.0) + prism (1.4.0) + proc_to_ast (0.2.0) + parser + rouge + unparser + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + racc (1.8.1) + rack (2.2.17) + rack-session (1.0.2) + rack (< 3) + rack-test (2.2.0) + rack (>= 1.3) + rackup (1.0.1) + rack (< 3) + webrick + rails (7.2.2.1) + actioncable (= 7.2.2.1) + actionmailbox (= 7.2.2.1) + actionmailer (= 7.2.2.1) + actionpack (= 7.2.2.1) + actiontext (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activemodel (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) + bundler (>= 1.15.0) + railties (= 7.2.2.1) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.0) + rdoc (6.14.2) + erb + psych (>= 4.0.0) + regexp_parser (2.10.0) + reline (0.6.1) + io-console (~> 0.5) + request_store (1.7.0) + rack (>= 1.4) + rexml (3.4.1) + rouge (4.5.2) + rspec (3.13.1) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-parameterized (1.0.2) + rspec-parameterized-core (< 2) + rspec-parameterized-table_syntax (< 2) + rspec-parameterized-core (1.0.1) + parser + proc_to_ast (>= 0.2.0) + rspec (>= 2.13, < 4) + unparser + rspec-parameterized-table_syntax (1.0.1) + binding_of_caller + rspec-parameterized-core (< 2) + rspec-rails (6.0.4) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + rspec-support (3.13.4) + rubocop (1.50.2) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.2.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-capybara (2.21.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.26.0) + rubocop (~> 1.41) + rubocop-graphql (0.19.0) + rubocop (>= 0.87, < 2) + rubocop-performance (1.23.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.25.1) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (2.31.0) + rubocop (~> 1.40) + rubocop-capybara (~> 2.17) + rubocop-factory_bot (~> 2.22) + rubocop-rspec_rails (~> 2.28) + rubocop-rspec_rails (2.29.0) + rubocop (~> 1.40) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + stringio (3.1.7) + thor (1.3.2) + timeout (0.4.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (2.6.0) + unparser (0.8.0) + diff-lcs (~> 1.6) + parser (>= 3.3.0) + prism (>= 1.4) + useragent (0.16.11) + webrick (1.9.1) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + zeitwerk (2.7.3) + +PLATFORMS + ruby + +DEPENDENCIES + activerecord-gitlab! + gitlab-database-load_balancing! + gitlab-rspec! + gitlab-safe_request_store! + gitlab-styles (~> 10.1.0) + gitlab-utils! + pg (~> 1.5.6) + pry + rails (~> 7.2) + rspec (~> 3.13) + rspec-parameterized (~> 1.0) + rspec-rails (~> 6.0.1) + rubocop (~> 1.50) + rubocop-rspec (~> 2.22) + +BUNDLED WITH + 2.6.9 diff --git a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec index 1e6bb8ddb850a3..ce8f298d50b900 100644 --- a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec +++ b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency 'gitlab-net-dns', '~> 0.12' spec.add_runtime_dependency "pg", '~> 1.5.6' - spec.add_runtime_dependency 'rails', '>= 7.1', '< 7.2' + spec.add_runtime_dependency 'rails', '>= 7.1' spec.add_development_dependency "gitlab-styles", "~> 10.1.0" spec.add_development_dependency "pg", '~> 1.5.6' -- GitLab From c7d21a705bebd8f7f0c1385403c024f8178109f6 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Mon, 21 Jul 2025 14:32:40 -0500 Subject: [PATCH 03/31] Update gitlab-styles for load balancing gem This transitively updates rubocop, fixing some errors when running against rails 7.2 Also fixes new rubocop errors from the styles upgrade. --- .../Gemfile.lock | 101 ++++++++++-------- .../Gemfile.next.lock | 75 ++++++------- .../gitlab-database-load_balancing.gemspec | 12 +-- 3 files changed, 100 insertions(+), 88 deletions(-) diff --git a/gems/gitlab-database-load_balancing/Gemfile.lock b/gems/gitlab-database-load_balancing/Gemfile.lock index e3bddf09d7221a..f9ae8f9022d1c5 100644 --- a/gems/gitlab-database-load_balancing/Gemfile.lock +++ b/gems/gitlab-database-load_balancing/Gemfile.lock @@ -137,12 +137,15 @@ GEM erubi (1.12.0) gitlab-net-dns (0.15.0) logger - gitlab-styles (10.1.0) - rubocop (~> 1.50.2) - rubocop-graphql (~> 0.18) - rubocop-performance (~> 1.15) - rubocop-rails (~> 2.17) - rubocop-rspec (~> 2.22) + gitlab-styles (13.1.0) + rubocop (= 1.71.1) + rubocop-capybara (~> 2.21.0) + rubocop-factory_bot (~> 2.26.1) + rubocop-graphql (~> 1.5.4) + rubocop-performance (~> 1.21.1) + rubocop-rails (~> 2.26.0) + rubocop-rspec (~> 3.0.4) + rubocop-rspec_rails (~> 2.30.0) globalid (1.2.1) activesupport (>= 6.1) i18n (1.12.0) @@ -153,6 +156,7 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.6.3) + language_server-protocol (3.17.0.5) logger (1.7.0) loofah (2.21.4) crass (~> 1.0.2) @@ -194,13 +198,14 @@ GEM nokogiri (1.16.8-x86_64-linux) racc (~> 1.4) parallel (1.22.1) - parser (3.2.2.3) + parser (3.3.8.0) ast (~> 2.4.1) racc pg (1.5.9) pp (0.6.2) prettyprint prettyprint (0.2.0) + prism (1.4.0) proc_to_ast (0.1.0) coderay parser @@ -255,12 +260,11 @@ GEM rdoc (6.14.2) erb psych (>= 4.0.0) - regexp_parser (2.7.0) + regexp_parser (2.10.0) reline (0.6.2) io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) - rexml (3.3.9) rspec (3.13.1) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -293,35 +297,38 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.13.4) - rubocop (1.50.2) + rubocop (1.71.1) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.18.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-capybara (2.21.0) rubocop (~> 1.41) - rubocop-factory_bot (2.23.1) - rubocop (~> 1.33) - rubocop-graphql (0.19.0) - rubocop (>= 0.87, < 2) - rubocop-performance (1.18.0) - rubocop (>= 1.7.0, < 2.0) - rubocop-ast (>= 0.4.0) - rubocop-rails (2.20.2) + rubocop-factory_bot (2.26.1) + rubocop (~> 1.61) + rubocop-graphql (1.5.4) + rubocop (>= 1.50, < 2) + rubocop-performance (1.21.1) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) - rubocop-rspec (2.22.0) - rubocop (~> 1.33) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop (>= 1.52.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.5) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) ruby-progressbar (1.11.0) securerandom (0.4.1) stringio (3.1.7) @@ -353,7 +360,7 @@ DEPENDENCIES gitlab-database-load_balancing! gitlab-rspec! gitlab-safe_request_store! - gitlab-styles (~> 10.1.0) + gitlab-styles (~> 13.1.0) gitlab-utils! pg (~> 1.5.6) pry @@ -361,8 +368,8 @@ DEPENDENCIES rspec (~> 3.13) rspec-parameterized (~> 1.0) rspec-rails (~> 6.0.1) - rubocop (~> 1.50) - rubocop-rspec (~> 2.22) + rubocop (~> 1.71.1) + rubocop-rspec (~> 3.0.4) CHECKSUMS actioncable (7.1.5.1) sha256=764637b5b2d97b94e412d562c177bfd16b0fd769d55c98846362f5263e8aaa0d @@ -398,13 +405,14 @@ CHECKSUMS gitlab-net-dns (0.15.0) sha256=d229aae205055b86b2ad166981257eb589ce6d6a146aa79b3ea2b1e5d9741f46 gitlab-rspec (0.1.0) gitlab-safe_request_store (0.1.0) - gitlab-styles (10.1.0) sha256=f42745f5397d042fe24cf2d0eb56c995b37f9f43d8fb79b834d197a1cafdc84a + gitlab-styles (13.1.0) sha256=46c7c5729616355868b7b40a4ffcd052b36346076042abe8cafaee1688cbf2c1 gitlab-utils (0.1.0) globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9 i18n (1.12.0) sha256=91e3cc1b97616d308707eedee413d82ee021d751c918661fb82152793e64aced io-console (0.8.1) sha256=1e15440a6b2f67b6ea496df7c474ed62c860ad11237f29b3bd187f054b925fcb irb (1.15.2) sha256=222f32952e278da34b58ffe45e8634bf4afc2dc7aa9da23fed67e581aa50fdba json (2.6.3) sha256=86aaea16adf346a2b22743d88f8dcceeb1038843989ab93cda44b5176c845459 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 loofah (2.21.4) sha256=2c18cd5db9fd92a48a270344e57a5b84cf22d668b78e1481f10e4f2cde4eb734 mail (2.8.1) sha256=ec3b9fadcf2b3755c78785cb17bc9a0ca9ee9857108a64b6f5cfc9c0b5bfc9ad @@ -427,10 +435,11 @@ CHECKSUMS nokogiri (1.16.8-x86_64-darwin) sha256=6c40d7dc444f752634bf6ee8b53a55c3cfca3f9df52be46b8abcc559ccd49e47 nokogiri (1.16.8-x86_64-linux) sha256=ed7b1f80713ac968dd93fe2b96fc3df6e448b73bd02dd77d5fc89ba92a1ed6d9 parallel (1.22.1) sha256=ebdf1f0c51f182df38522f70ba770214940bef998cdb6e00f36492b29699761f - parser (3.2.2.3) sha256=10685f358ab36ffea2252dc4952e5b8fad3a297a8152a85f59adc982747b91eb + parser (3.3.8.0) sha256=2476364142b307fa5a1b1ece44f260728be23858a9c71078e956131a75453c45 pg (1.5.9) sha256=761efbdf73b66516f0c26fcbe6515dc7500c3f0aa1a1b853feae245433c64fdc pp (0.6.2) sha256=947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.4.0) sha256=dc0e3e00e93160213dc2a65519d9002a4a1e7b962db57d444cf1a71565bb703e proc_to_ast (0.1.0) sha256=92a73fa66e2250a83f8589f818b0751bcf227c68f85916202df7af85082f8691 pry (0.14.2) sha256=c4fe54efedaca1d351280b45b8849af363184696fcac1c72e0415f9bdac4334d psych (5.2.6) sha256=814328aa5dcb6d604d32126a20bc1cbcf05521a5b49dbb1a8b30a07e580f316e @@ -447,10 +456,9 @@ CHECKSUMS rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a rake (13.1.0) sha256=be6a3e1aa7f66e6c65fa57555234eb75ce4cf4ada077658449207205474199c6 rdoc (6.14.2) sha256=9fdd44df130f856ae70cc9a264dfd659b9b40de369b16581f4ab746e42439226 - regexp_parser (2.7.0) sha256=f8b8b7f34cc53c907fad6aec2b9da996a4311a0ddd92f3bfd3b999de5420c234 + regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61 reline (0.6.2) sha256=1dad26a6008872d59c8e05244b119347c9f2ddaf4a53dce97856cd5f30a02846 request_store (1.5.1) sha256=07a204d161590789f2b1d27f9f0eadcdecd6d868cb2f03240250e1bc747df78e - rexml (3.3.9) sha256=d71875b85299f341edf47d44df0212e7658cbdf35aeb69cefdb63f57af3137c9 rspec (3.13.1) sha256=b9f9a58fa915b8d94a1d6b3195fe6dd28c4c34836a6097015142c4a9ace72140 rspec-core (3.13.5) sha256=ab3f682897c6131c67f9a17cfee5022a597f283aebe654d329a565f9937a4fa3 rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 @@ -460,14 +468,15 @@ CHECKSUMS rspec-parameterized-table_syntax (1.0.1) sha256=ffead8f21f0711b3cdf8b74386f2ef7ac93b39c40b60658a5eda97072580f2fc rspec-rails (6.0.3) sha256=6d1812cfaf18dba5a08d7e30c85149b24a220fae064853a96e451376be6fd820 rspec-support (3.13.4) sha256=184b1814f6a968102b57df631892c7f1990a91c9a3b9e80ef892a0fc2a71a3f7 - rubocop (1.50.2) sha256=7cfeb0616f686ac61d049beae89f31446792d7e9f5728152657548f70aa78650 - rubocop-ast (1.29.0) sha256=d1da2ab279a074baefc81758ac430c5768a8da8c7438dd4e5819ce5984d00ba1 - rubocop-capybara (2.18.0) sha256=66b256755101f76dc455ba9694e2414bc957db5200401d204b00bc835401d605 - rubocop-factory_bot (2.23.1) sha256=c19ee30c02e591f4293c07e943e22b7999c545d5010aac4d79621ee310850c4f - rubocop-graphql (0.19.0) sha256=ba4b2fc91c9f0fda47e0870a6ae15a1e5525d6caffcb150dc88b00caaacc3e43 - rubocop-performance (1.18.0) sha256=4c9d74f1b5bfaffb5b1cdb843279364198ac804e2644ae194615834dd011e02e - rubocop-rails (2.20.2) sha256=d20cbd613900fa22bcf85a7fba78ab68b21fc4f90b1e73c97284d40674332417 - rubocop-rspec (2.22.0) sha256=2d7493222c81c78ad304ddd81aaf64b3543bcfac6d3d8706c220331921753a03 + rubocop (1.71.1) sha256=d3dfd1e484a3a619dcf76c6a4fba694cd833921e4fd254d111845c26bcecfcfa + rubocop-ast (1.46.0) sha256=0da7f6ad5b98614f89b74f11873c191059c823eae07d6ffd40a42a3338f2232b + rubocop-capybara (2.21.0) sha256=5d264efdd8b6c7081a3d4889decf1451a1cfaaec204d81534e236bc825b280ab + rubocop-factory_bot (2.26.1) sha256=8de13cd4edcee5ca800f255188167ecef8dbfc3d1fae9f15734e9d2e755392aa + rubocop-graphql (1.5.4) sha256=2d888d40b08577daf1e74ca4623be1e3058c1a93543d5a7220818f561a254192 + rubocop-performance (1.21.1) sha256=5cf20002a544275ad6aa99abca4b945d2a2ed71be925c38fe83700360ed8734e + rubocop-rails (2.26.2) sha256=f5561a09d6afd2f54316f3f0f6057338ca55b6c24a25ba6a938d3ed0fded84ad + rubocop-rspec (3.0.5) sha256=c6a8e29fb1b00d227c32df159e92f5ebb9e0ff734e52955fb13aff5c74977e0f + rubocop-rspec_rails (2.30.0) sha256=888112e83f9d7ef7ad2397e9d69a0b9614a4bae24f072c399804a180f80c4c46 ruby-progressbar (1.11.0) sha256=cc127db3866dc414ffccbf92928a241e585b3aa2b758a5563e74a6ee0f57d50a securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 stringio (3.1.7) sha256=5b78b7cb242a315fb4fca61a8255d62ec438f58da2b90be66048546ade4507fa diff --git a/gems/gitlab-database-load_balancing/Gemfile.next.lock b/gems/gitlab-database-load_balancing/Gemfile.next.lock index e108c018302098..4ecad0a049ba19 100644 --- a/gems/gitlab-database-load_balancing/Gemfile.next.lock +++ b/gems/gitlab-database-load_balancing/Gemfile.next.lock @@ -131,12 +131,15 @@ GEM erubi (1.13.1) gitlab-net-dns (0.15.0) logger - gitlab-styles (10.1.0) - rubocop (~> 1.50.2) - rubocop-graphql (~> 0.18) - rubocop-performance (~> 1.15) - rubocop-rails (~> 2.17) - rubocop-rspec (~> 2.22) + gitlab-styles (13.1.0) + rubocop (= 1.71.1) + rubocop-capybara (~> 2.21.0) + rubocop-factory_bot (~> 2.26.1) + rubocop-graphql (~> 1.5.4) + rubocop-performance (~> 1.21.1) + rubocop-rails (~> 2.26.0) + rubocop-rspec (~> 3.0.4) + rubocop-rspec_rails (~> 2.30.0) globalid (1.2.1) activesupport (>= 6.1) i18n (1.14.7) @@ -146,7 +149,8 @@ GEM pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.12.2) + json (2.13.0) + language_server-protocol (3.17.0.5) logger (1.7.0) loofah (2.24.1) crass (~> 1.0.2) @@ -171,7 +175,7 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.18.8) + nokogiri (1.18.9) mini_portile2 (~> 2.8.2) racc (~> 1.4) parallel (1.27.0) @@ -238,12 +242,11 @@ GEM erb psych (>= 4.0.0) regexp_parser (2.10.0) - reline (0.6.1) + reline (0.6.2) io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - rexml (3.4.1) - rouge (4.5.2) + rouge (4.6.0) rspec (3.13.1) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -276,48 +279,48 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.13.4) - rubocop (1.50.2) + rubocop (1.71.1) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) + unicode-display_width (>= 2.4.0, < 4.0) rubocop-ast (1.46.0) parser (>= 3.3.7.2) prism (~> 1.4) rubocop-capybara (2.21.0) rubocop (~> 1.41) - rubocop-factory_bot (2.26.0) - rubocop (~> 1.41) - rubocop-graphql (0.19.0) - rubocop (>= 0.87, < 2) - rubocop-performance (1.23.1) + rubocop-factory_bot (2.26.1) + rubocop (~> 1.61) + rubocop-graphql (1.5.4) + rubocop (>= 1.50, < 2) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.25.1) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) + rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (2.31.0) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) - rubocop-rspec_rails (~> 2.28) - rubocop-rspec_rails (2.29.0) - rubocop (~> 1.40) + rubocop-rspec (3.0.5) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) ruby-progressbar (1.13.0) securerandom (0.4.1) stringio (3.1.7) - thor (1.3.2) + thor (1.4.0) timeout (0.4.3) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.6.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) unparser (0.8.0) diff-lcs (~> 1.6) parser (>= 3.3.0) @@ -338,7 +341,7 @@ DEPENDENCIES gitlab-database-load_balancing! gitlab-rspec! gitlab-safe_request_store! - gitlab-styles (~> 10.1.0) + gitlab-styles (~> 13.1.0) gitlab-utils! pg (~> 1.5.6) pry @@ -346,8 +349,8 @@ DEPENDENCIES rspec (~> 3.13) rspec-parameterized (~> 1.0) rspec-rails (~> 6.0.1) - rubocop (~> 1.50) - rubocop-rspec (~> 2.22) + rubocop (~> 1.71.1) + rubocop-rspec (~> 3.0.4) BUNDLED WITH 2.6.9 diff --git a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec index ce8f298d50b900..17e71abac0e521 100644 --- a/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec +++ b/gems/gitlab-database-load_balancing/gitlab-database-load_balancing.gemspec @@ -16,16 +16,16 @@ Gem::Specification.new do |spec| spec.files = Dir['lib/**/*.rb'] spec.require_paths = ["lib"] - spec.add_runtime_dependency 'gitlab-net-dns', '~> 0.12' - spec.add_runtime_dependency "pg", '~> 1.5.6' - spec.add_runtime_dependency 'rails', '>= 7.1' + spec.add_dependency 'gitlab-net-dns', '~> 0.12' + spec.add_dependency "pg", '~> 1.5.6' + spec.add_dependency 'rails', '>= 7.1' - spec.add_development_dependency "gitlab-styles", "~> 10.1.0" + spec.add_development_dependency "gitlab-styles", "~> 13.1.0" spec.add_development_dependency "pg", '~> 1.5.6' spec.add_development_dependency "pry" spec.add_development_dependency "rspec", "~> 3.13" spec.add_development_dependency "rspec-parameterized", "~> 1.0" spec.add_development_dependency "rspec-rails", "~> 6.0.1" - spec.add_development_dependency "rubocop", "~> 1.50" - spec.add_development_dependency "rubocop-rspec", "~> 2.22" + spec.add_development_dependency "rubocop", "~> 1.71.1" + spec.add_development_dependency "rubocop-rspec", "~> 3.0.4" end -- GitLab From e591fbfe7af24f264ce86ad4a20bca2971f82281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 22 Nov 2023 10:49:50 +0100 Subject: [PATCH 04/31] Move `Gitlab::Database::LoadBalancing` to Gem --- Gemfile | 2 +- Gemfile.lock | 9 ++++ Gemfile.next.lock | 9 ++++ config/initializers/load_balancing.rb | 36 ++++++++++++++ .../.rubocop.yml | 47 +++++++++++++++++++ .../.rubocop_todo.yml | 41 ++++++++++++++++ gems/gitlab-database-load_balancing/README.md | 2 +- .../lib}/gitlab/database/load_balancing.rb | 42 +++++++++++++++-- .../load_balancing/action_cable_callbacks.rb | 0 .../database/load_balancing/callbacks.rb | 43 +++++++++++++++++ .../database/load_balancing/configuration.rb | 8 ++-- .../load_balancing/connection_proxy.rb | 2 + .../gitlab/database/load_balancing/host.rb | 13 ++--- .../database/load_balancing/host_list.rb | 3 +- .../database/load_balancing/load_balancer.rb | 15 +++--- .../database/load_balancing/primary_host.rb | 2 +- .../database/load_balancing/resolver.rb | 0 .../load_balancing/service_discovery.rb | 21 ++++----- .../service_discovery/sampler.rb | 4 +- .../gitlab/database/load_balancing/session.rb | 0 .../gitlab/database/load_balancing/setup.rb | 4 +- .../database/load_balancing/srv_resolver.rb | 7 ++- .../database/load_balancing/sticking.rb | 16 ++----- .../spec}/fixtures/dns/a_rr.json | 0 .../a_with_aaaa_rr_in_additional_section.json | 0 .../spec}/fixtures/dns/aaaa_rr.json | 0 .../srv_with_a_rr_in_additional_section.json | 0 .../action_cable_callbacks_spec.rb | 0 .../load_balancing/configuration_spec.rb | 8 ++-- .../load_balancing/connection_proxy_spec.rb | 8 ++-- .../database/load_balancing/host_list_spec.rb | 6 ++- .../database/load_balancing/host_spec.rb | 16 +++---- .../load_balancing/load_balancer_spec.rb | 10 ++-- .../load_balancing/primary_host_spec.rb | 2 +- .../database/load_balancing/resolver_spec.rb | 0 .../service_discovery/sampler_spec.rb | 4 +- .../load_balancing/service_discovery_spec.rb | 16 +++---- .../database/load_balancing/session_spec.rb | 0 .../database/load_balancing/setup_spec.rb | 4 +- .../load_balancing/srv_resolver_spec.rb | 5 +- .../database/load_balancing/sticking_spec.rb | 19 +++----- .../transaction_leaking_spec.rb | 12 ++--- .../spec/spec_helper.rb | 14 ++++++ .../spec/support/application_record.rb | 11 +++++ .../spec/support/database_replica.rb | 28 +++++++++++ lib/gitlab/database.rb | 24 ++-------- 46 files changed, 381 insertions(+), 132 deletions(-) create mode 100644 gems/gitlab-database-load_balancing/.rubocop_todo.yml rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing.rb (57%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/action_cable_callbacks.rb (100%) create mode 100644 gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/configuration.rb (92%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/connection_proxy.rb (99%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/host.rb (96%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/host_list.rb (92%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/load_balancer.rb (96%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/primary_host.rb (96%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/resolver.rb (100%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/service_discovery.rb (94%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/service_discovery/sampler.rb (93%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/session.rb (100%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/setup.rb (94%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/srv_resolver.rb (84%) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/sticking.rb (91%) rename {spec => gems/gitlab-database-load_balancing/spec}/fixtures/dns/a_rr.json (100%) rename {spec => gems/gitlab-database-load_balancing/spec}/fixtures/dns/a_with_aaaa_rr_in_additional_section.json (100%) rename {spec => gems/gitlab-database-load_balancing/spec}/fixtures/dns/aaaa_rr.json (100%) rename {spec => gems/gitlab-database-load_balancing/spec}/fixtures/dns/srv_with_a_rr_in_additional_section.json (100%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/action_cable_callbacks_spec.rb (100%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/configuration_spec.rb (94%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/connection_proxy_spec.rb (97%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/host_list_spec.rb (93%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/host_spec.rb (96%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/load_balancer_spec.rb (98%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/primary_host_spec.rb (96%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/resolver_spec.rb (100%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/service_discovery/sampler_spec.rb (93%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/service_discovery_spec.rb (96%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/session_spec.rb (100%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/setup_spec.rb (97%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/srv_resolver_spec.rb (91%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/sticking_spec.rb (92%) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/transaction_leaking_spec.rb (89%) create mode 100644 gems/gitlab-database-load_balancing/spec/support/application_record.rb create mode 100644 gems/gitlab-database-load_balancing/spec/support/database_replica.rb diff --git a/Gemfile b/Gemfile index 63ab2e4885d291..d58b8e1b65cdb2 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ group :monorepo do end gem 'gitlab-backup-cli', path: 'gems/gitlab-backup-cli', require: 'gitlab/backup/cli', feature_category: :backup_restore - +gem 'gitlab-database-load_balancing', path: 'gems/gitlab-database-load_balancing' # rubocop:todo Gemfile/MissingFeatureCategory gem 'gitlab-secret_detection', '< 1.0', feature_category: :secret_detection # Responders respond_to and respond_with diff --git a/Gemfile.lock b/Gemfile.lock index 18ccdea1a726da..646959f19b2758 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -67,6 +67,14 @@ PATH rexml (~> 3.4.0) thor (~> 1.3) +PATH + remote: gems/gitlab-database-load_balancing + specs: + gitlab-database-load_balancing (0.1.0) + gitlab-net-dns (~> 0.12) + pg (~> 1.5.6) + rails (>= 7.1) + PATH remote: gems/gitlab-housekeeper specs: @@ -2151,6 +2159,7 @@ DEPENDENCIES gitlab-cloud-connector (~> 1.21) gitlab-crystalball (~> 1.1.0) gitlab-dangerfiles (~> 4.9.0) + gitlab-database-load_balancing! gitlab-duo-workflow-service-client (~> 0.2)! gitlab-experiment (~> 0.9.1) gitlab-fog-azure-rm (~> 2.2.0) diff --git a/Gemfile.next.lock b/Gemfile.next.lock index 792875ddcf02f8..ec024424f3555f 100644 --- a/Gemfile.next.lock +++ b/Gemfile.next.lock @@ -67,6 +67,14 @@ PATH rexml (~> 3.4.0) thor (~> 1.3) +PATH + remote: gems/gitlab-database-load_balancing + specs: + gitlab-database-load_balancing (0.1.0) + gitlab-net-dns (~> 0.12) + pg (~> 1.5.6) + rails (>= 7.1) + PATH remote: gems/gitlab-housekeeper specs: @@ -2146,6 +2154,7 @@ DEPENDENCIES gitlab-cloud-connector (~> 1.21) gitlab-crystalball (~> 1.1.0) gitlab-dangerfiles (~> 4.9.0) + gitlab-database-load_balancing! gitlab-duo-workflow-service-client (~> 0.2)! gitlab-experiment (~> 0.9.1) gitlab-fog-azure-rm (~> 2.2.0) diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 32b8e6e5a738d9..d8d18466ac9748 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -13,6 +13,42 @@ end end +# Configure load balancing +Gitlab::Database::LoadBalancing.enabled = !Gitlab::Runtime.rake? +Gitlab::Database::LoadBalancing.default_pool_size = Gitlab::Database.default_pool_size + +Gitlab::Cluster::LifecycleEvents.on_worker_start do + Gitlab::Database::LoadBalancing.enabled = !Gitlab::Runtime.rake? + Gitlab::Database::LoadBalancing.default_pool_size = Gitlab::Database.default_pool_size +end + +Gitlab::Database::LoadBalancing.base_models = + ::Gitlab::Database.database_base_models_using_load_balancing.values.freeze + +# Configure callbacks +Gitlab::Database::LoadBalancing::Callbacks.configure! do |callbacks| + hosts_gauge = Gitlab::Metrics.gauge(:db_load_balancing_hosts, 'Current number of load balancing hosts') + + callbacks.logger_proc = -> do + Gitlab::Database::LoadBalancing::Logger.build + end + callbacks.metrics_host_gauge_proc = ->(labels, value) do + hosts_gauge.set(labels, value) + end + callbacks.track_exception_proc = ->(exception) do + Gitlab::ErrorTracking.track_exception(exception) + end + callbacks.set_wal_for_proc = ->(key, value, ex:) do + Gitlab::Redis::DbLoadBalancing.with { |redis| redis.set(key, value, ex: ex) } + end + callbacks.get_wal_for_proc = ->(key) do + Gitlab::Redis::DbLoadBalancing.with { |redis| redis.get(key) } + end + callbacks.del_wal_for_proc = ->(key) do + Gitlab::Redis::DbLoadBalancing.with { |redis| redis.del(key) } + end +end + Gitlab::Database::LoadBalancing.base_models.each do |model| # The load balancer needs to be configured immediately, and re-configured # after forking. This ensures queries that run before forking use the load diff --git a/gems/gitlab-database-load_balancing/.rubocop.yml b/gems/gitlab-database-load_balancing/.rubocop.yml index 583fa8227eec03..8340cf13f69c26 100644 --- a/gems/gitlab-database-load_balancing/.rubocop.yml +++ b/gems/gitlab-database-load_balancing/.rubocop.yml @@ -1,6 +1,53 @@ inherit_from: + - .rubocop_todo.yml - ../config/rubocop.yml Gemfile/MissingFeatureCategory: Exclude: - 'Gemfile' + +Database/MultipleDatabases: + Exclude: + - 'lib/gitlab/database/load_balancing/load_balancer.rb' + - 'spec/gitlab/database/load_balancing/host_list_spec.rb' + - 'spec/gitlab/database/load_balancing/host_spec.rb' + - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' + - 'spec/gitlab/database/load_balancing/setup_spec.rb' + - 'spec/gitlab/database/load_balancing/sticking_spec.rb' + +Graphql/ResolverType: + Exclude: + - 'lib/gitlab/database/load_balancing/resolver.rb' + - 'lib/gitlab/database/load_balancing/srv_resolver.rb' + +Rails/SkipsModelValidations: + Exclude: + - 'spec/gitlab/database/load_balancing/connection_proxy_spec.rb' + - 'spec/gitlab/database/load_balancing_spec.rb' + +RSpec/ExpectInHook: + Exclude: + - 'spec/gitlab/database/load_balancing/host_spec.rb' + - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' + +RSpec/ImplicitSubject: + Exclude: + - 'spec/gitlab/database/load_balancing/configuration_spec.rb' + +RSpec/MultipleMemoizedHelpers: + Max: 9 + +RSpec/VerifiedDoubles: + Exclude: + - 'spec/gitlab/database/load_balancing/configuration_spec.rb' + - 'spec/gitlab/database/load_balancing/connection_proxy_spec.rb' + - 'spec/gitlab/database/load_balancing/host_list_spec.rb' + - 'spec/gitlab/database/load_balancing/host_spec.rb' + - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' + - 'spec/gitlab/database/load_balancing/resolver_spec.rb' + - 'spec/gitlab/database/load_balancing/service_discovery_spec.rb' + - 'spec/gitlab/database/load_balancing/setup_spec.rb' + - 'spec/gitlab/database/load_balancing_spec.rb' + +Layout/LineLength: + Max: 129 diff --git a/gems/gitlab-database-load_balancing/.rubocop_todo.yml b/gems/gitlab-database-load_balancing/.rubocop_todo.yml new file mode 100644 index 00000000000000..12a7b201f51cba --- /dev/null +++ b/gems/gitlab-database-load_balancing/.rubocop_todo.yml @@ -0,0 +1,41 @@ +Lint/AssignmentInCondition: + Exclude: + - 'lib/gitlab/database/load_balancing/configuration.rb' + - 'lib/gitlab/database/load_balancing/host.rb' + - 'lib/gitlab/database/load_balancing/load_balancer.rb' + +Lint/DuplicateBranch: + Exclude: + - 'lib/gitlab/database/load_balancing/load_balancer.rb' + +Lint/EmptyBlock: + Exclude: + - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' + +Lint/RedundantCopDisableDirective: + Exclude: + - 'lib/gitlab/database/load_balancing.rb' + +Lint/UnusedMethodArgument: + Exclude: + - 'lib/gitlab/database/load_balancing/connection_proxy.rb' + - 'lib/gitlab/database/load_balancing/primary_host.rb' + +Naming/RescuedExceptionsVariableName: + Exclude: + - 'lib/gitlab/database/load_balancing/load_balancer.rb' + - 'lib/gitlab/database/load_balancing/service_discovery.rb' + - 'spec/gitlab/database/load_balancing/host_spec.rb' + - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' + +Style/GuardClause: + Exclude: + - 'lib/gitlab/database/load_balancing/load_balancer.rb' + +Style/Lambda: + Exclude: + - 'lib/gitlab/database/load_balancing/action_cable_callbacks.rb' + +Style/RedundantSelf: + Exclude: + - 'lib/gitlab/database/load_balancing/service_discovery.rb' diff --git a/gems/gitlab-database-load_balancing/README.md b/gems/gitlab-database-load_balancing/README.md index e1a963dba5087c..fb05fa373fe9dd 100644 --- a/gems/gitlab-database-load_balancing/README.md +++ b/gems/gitlab-database-load_balancing/README.md @@ -1,3 +1,3 @@ # GitLab Database Load Balancing -This gem is a stub for a move of all `Gitlab::Database::LoadBalancing` code. +TODO diff --git a/lib/gitlab/database/load_balancing.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb similarity index 57% rename from lib/gitlab/database/load_balancing.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb index bc4d33291039ff..55f57ba27f89f8 100644 --- a/lib/gitlab/database/load_balancing.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb @@ -1,5 +1,15 @@ # frozen_string_literal: true +require 'pg' +require 'active_support/time_with_zone' +require 'active_record' +require 'active_record/database_configurations' +require 'active_job' + +Dir['load_balancing/**/*.rb', base: File.dirname(__FILE__)].each do |file| + require_relative file +end + module Gitlab module Database module LoadBalancing @@ -18,9 +28,9 @@ module LoadBalancing ActiveRecord::ConnectionNotEstablished ].freeze - def self.base_models - @base_models ||= ::Gitlab::Database.database_base_models_using_load_balancing.values.freeze - end + mattr_accessor :base_models + mattr_accessor :default_pool_size + mattr_accessor :enabled, default: true def self.each_load_balancer return to_enum(__method__) unless block_given? @@ -53,7 +63,7 @@ def self.release_hosts def self.db_role_for_connection(connection) return ROLE_UNKNOWN if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy) - db_config = Database.db_config_for_connection(connection) + db_config = db_config_for_connection(connection) return ROLE_UNKNOWN unless db_config if db_config.name.ends_with?(LoadBalancer::REPLICA_SUFFIX) @@ -62,6 +72,30 @@ def self.db_role_for_connection(connection) ROLE_PRIMARY end end + + def self.db_config_for_connection(connection) + return unless connection + + # For a ConnectionProxy we want to avoid ambiguous db_config as it may + # sometimes default to replica so we always return the primary config + # instead. + if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy) + return connection.load_balancer.configuration.db_config + end + + # During application init we might receive `NullPool` + return unless connection.respond_to?(:pool) && + connection.pool.respond_to?(:db_config) + + db_config = connection.pool.db_config + db_config unless empty_config?(db_config) + end + + def self.empty_config?(db_config) + return true unless db_config + + db_config.is_a?(ActiveRecord::ConnectionAdapters::NullPool::NullConfig) + end end end end diff --git a/lib/gitlab/database/load_balancing/action_cable_callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/action_cable_callbacks.rb similarity index 100% rename from lib/gitlab/database/load_balancing/action_cable_callbacks.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/action_cable_callbacks.rb diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb new file mode 100644 index 00000000000000..086819e016ba93 --- /dev/null +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Gitlab + module Database + module LoadBalancing + module Callbacks + mattr_accessor :logger_proc + mattr_accessor :metrics_host_gauge_proc, :track_exception_proc + mattr_accessor :set_wal_for_proc, :get_wal_for_proc, :del_wal_for_proc + + NULL_LOGGER = Logger.new(File::NULL) + + def self.configure! + yield(self) + end + + def self.set_wal_for(key, wal, ex:) + set_wal_for_proc&.call(key, wal, ex: ex) + end + + def self.get_wal_for(key) + get_wal_for_proc&.call(key) + end + + def self.del_wal_for(key) + del_wal_for_proc&.call(key) + end + + def self.logger + logger_proc&.call || NULL_LOGGER + end + + def self.metrics_host_gauge(labels, value) + metrics_host_gauge_proc&.call(labels, value) + end + + def self.track_exception(ex) + track_exception_proc&.call(ex) + end + end + end + end +end diff --git a/lib/gitlab/database/load_balancing/configuration.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb similarity index 92% rename from lib/gitlab/database/load_balancing/configuration.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb index 15adf0dbf24d6b..4bcc3fde99c0ba 100644 --- a/lib/gitlab/database/load_balancing/configuration.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'active_support/core_ext/numeric/bytes' + module Gitlab module Database module LoadBalancing @@ -82,7 +84,7 @@ def pool_size # 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 + Gitlab::Database::LoadBalancing.default_pool_size end # Returns `true` if the use of load balancing replicas should be @@ -91,7 +93,7 @@ def pool_size # This is disabled for Rake tasks to ensure e.g. database migrations # always produce consistent results. def load_balancing_enabled? - return false if Gitlab::Runtime.rake? + return false unless Gitlab::Database::LoadBalancing.enabled hosts.any? || service_discovery_enabled? end @@ -99,7 +101,7 @@ def load_balancing_enabled? # This is disabled for Rake tasks to ensure e.g. database migrations # always produce consistent results. def service_discovery_enabled? - return false if Gitlab::Runtime.rake? + return false unless Gitlab::Database::LoadBalancing.enabled service_discovery[:record].present? end diff --git a/lib/gitlab/database/load_balancing/connection_proxy.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/connection_proxy.rb similarity index 99% rename from lib/gitlab/database/load_balancing/connection_proxy.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/connection_proxy.rb index fc54353ee88afe..534b02c096dae8 100644 --- a/lib/gitlab/database/load_balancing/connection_proxy.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/connection_proxy.rb @@ -149,3 +149,5 @@ def read_only_transaction? end end end + +# rubocop:enable GitlabSecurity/PublicSend diff --git a/lib/gitlab/database/load_balancing/host.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb similarity index 96% rename from lib/gitlab/database/load_balancing/host.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb index f77eedf265d890..b95b1e30f7b929 100644 --- a/lib/gitlab/database/load_balancing/host.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb @@ -7,7 +7,8 @@ module LoadBalancing class Host attr_reader :pool, :last_checked_at, :intervals, :load_balancer, :host, :port - delegate :connection, :release_connection, :enable_query_cache!, :disable_query_cache!, :query_cache_enabled, to: :pool + delegate :connection, :release_connection, :enable_query_cache!, :disable_query_cache!, :query_cache_enabled, + to: :pool CONNECTION_ERRORS = [ ActionView::Template::Error, @@ -84,9 +85,9 @@ def initialize(host, load_balancer, port: nil) # timeout - The time after which the pool should be forcefully # disconnected. def disconnect!(timeout: 120) - start_time = ::Gitlab::Metrics::System.monotonic_time + start_time = ::Gitlab::Utils::System.monotonic_time - while (::Gitlab::Metrics::System.monotonic_time - start_time) <= timeout + while (::Gitlab::Utils::System.monotonic_time - start_time) <= timeout return if try_disconnect sleep(2) @@ -115,7 +116,7 @@ def pool_disconnect! end def offline! - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :host_offline, message: 'Marking host as offline', db_host: @host, @@ -135,7 +136,7 @@ def online? # Log that the host came back online if it was previously offline if @online && !was_online - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :host_online, message: 'Host is online after replica status check', db_host: @host, @@ -145,7 +146,7 @@ def online? ) # Always log if the host goes offline elsif !@online - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :host_offline, message: 'Host is offline after replica status check', db_host: @host, diff --git a/lib/gitlab/database/load_balancing/host_list.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host_list.rb similarity index 92% rename from lib/gitlab/database/load_balancing/host_list.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host_list.rb index fb3175c7d5d899..7a3750f637b430 100644 --- a/lib/gitlab/database/load_balancing/host_list.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host_list.rb @@ -10,7 +10,6 @@ def initialize(hosts = []) @hosts = hosts.shuffle @index = 0 @mutex = Mutex.new - @hosts_gauge = Gitlab::Metrics.gauge(:db_load_balancing_hosts, 'Current number of load balancing hosts') set_metrics! end @@ -80,7 +79,7 @@ def next_host end def set_metrics! - @hosts_gauge.set({}, @hosts.length) + Callbacks.metrics_host_gauge({}, @hosts.length) end end end diff --git a/lib/gitlab/database/load_balancing/load_balancer.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/load_balancer.rb similarity index 96% rename from lib/gitlab/database/load_balancing/load_balancer.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/load_balancer.rb index 99ddce46a15499..4becd23c8f51e9 100644 --- a/lib/gitlab/database/load_balancing/load_balancer.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/load_balancer.rb @@ -76,7 +76,7 @@ def read(&block) # times before using the primary instead. will_retry = conflict_retried < @host_list.length * 3 - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :host_query_conflict, message: 'Query conflict on host', conflict_retried: conflict_retried, @@ -101,7 +101,7 @@ def read(&block) end end - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :no_secondaries_available, message: 'No secondaries were available, using primary instead', conflict_retried: conflict_retried, @@ -136,7 +136,7 @@ def read_write transaction_open = connection.transaction_open? if attempt && attempt > 1 - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :read_write_retry, message: 'A read_write block was retried because of connection error' ) @@ -147,7 +147,7 @@ def read_write # No leaking will happen on the final attempt. Leaks are caused by subsequent retries not_final_attempt = attempt && attempt < attempts if transaction_open && connection_error?(e) && not_final_attempt - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :transaction_leak, message: 'A write transaction has leaked during database fail-over' ) @@ -315,7 +315,6 @@ def create_replica_connection_pool(pool_size, host = nil, port = nil) # ActiveRecord::ConnectionAdapters::ConnectionHandler handles fetching, # and caching for connections pools for each "connection", so we # leverage that. - # rubocop:disable Database/MultipleDatabases def pool ActiveRecord::Base.connection_handler.retrieve_connection_pool( @configuration.connection_specification_name, @@ -323,7 +322,6 @@ def pool shard: ActiveRecord::Base.default_shard ) || raise(::ActiveRecord::ConnectionNotEstablished) end - # rubocop:enable Database/MultipleDatabases def wal_diff(location1, location2) read_write do |connection| @@ -372,7 +370,7 @@ def get_write_location(ar_connection) END AS location; NEWSQL else - <<~SQL + <<~SQL.squish SELECT pg_current_wal_insert_lsn()::text AS location SQL end @@ -384,7 +382,8 @@ def get_write_location(ar_connection) def raise_if_concurrent_ruby! Gitlab::Utils.raise_if_concurrent_ruby!(:db) rescue StandardError => e - Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e) + ::Gitlab::Database::LoadBalancing::Callbacks.track_exception(e) + raise if Rails.env.development? || Rails.env.test? end end end diff --git a/lib/gitlab/database/load_balancing/primary_host.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/primary_host.rb similarity index 96% rename from lib/gitlab/database/load_balancing/primary_host.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/primary_host.rb index 0359f9e9994ebd..f23b63ce9c5496 100644 --- a/lib/gitlab/database/load_balancing/primary_host.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/primary_host.rb @@ -53,7 +53,7 @@ def disconnect!(timeout: 120) end def offline! - ::Gitlab::Database::LoadBalancing::Logger.warn( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :host_offline, message: 'Marking primary host as offline' ) diff --git a/lib/gitlab/database/load_balancing/resolver.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/resolver.rb similarity index 100% rename from lib/gitlab/database/load_balancing/resolver.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/resolver.rb diff --git a/lib/gitlab/database/load_balancing/service_discovery.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb similarity index 94% rename from lib/gitlab/database/load_balancing/service_discovery.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb index 890dde3c843876..08945b91dd5d02 100644 --- a/lib/gitlab/database/load_balancing/service_discovery.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb @@ -17,8 +17,7 @@ class ServiceDiscovery attr_accessor :refresh_thread, :refresh_thread_last_run, :refresh_thread_interruption_logged - attr_reader :interval, :record, :record_type, :disconnect_timeout, - :load_balancer + attr_reader :interval, :record, :record_type, :disconnect_timeout, :load_balancer MAX_SLEEP_ADJUSTMENT = 10 MAX_DISCOVERY_RETRIES = 3 @@ -96,9 +95,9 @@ def perform_service_discovery rescue StandardError => error # Any exceptions that might occur should be reported to # Sentry, instead of silently terminating this thread. - Gitlab::ErrorTracking.track_exception(error) + ::Gitlab::Database::LoadBalancing::Callbacks.track_exception(error) - Gitlab::Database::LoadBalancing::Logger.error( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.error( event: :service_discovery_failure, message: "Service discovery encountered an error: #{error.message}", host_list_length: load_balancer.host_list.length, @@ -124,7 +123,7 @@ def refresh_if_necessary current = addresses_from_load_balancer if from_dns != current - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :host_list_update, message: "Updating the host list for service discovery", host_list_length: from_dns.length, @@ -212,7 +211,7 @@ def log_refresh_thread_interruption return if refresh_thread_last_run.blank? || refresh_thread_interruption_logged || (refresh_thread_last_run + DISCOVERY_THREAD_REFRESH_DELTA.minutes).future? - Gitlab::Database::LoadBalancing::Logger.error( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.error( event: :service_discovery_refresh_thread_interrupt, refresh_thread_last_run: refresh_thread_last_run, thread_status: refresh_thread&.status&.to_s, @@ -233,12 +232,12 @@ def record_type_for(type) def addresses_from_srv_record(response) srv_resolver = SrvResolver.new(resolver, response.additional) - response.answer.map do |r| + response.answer.filter_map do |r| address = srv_resolver.address_for(r.host.to_s) next unless address Address.new(address.to_s, r.port) - end.compact + end end def addresses_from_a_record(resources) @@ -253,14 +252,14 @@ def sampler def disconnect_old_hosts(hosts) return unless hosts.present? - gentle_disconnect_start = ::Gitlab::Metrics::System.monotonic_time + gentle_disconnect_start = ::Gitlab::Utils::System.monotonic_time gentle_disconnect_deadline = gentle_disconnect_start + disconnect_timeout hosts_to_disconnect = hosts gentle_disconnected_hosts = [] gentle_disconnect_duration = Benchmark.realtime do - while ::Gitlab::Metrics::System.monotonic_time < gentle_disconnect_deadline + while ::Gitlab::Utils::System.monotonic_time < gentle_disconnect_deadline newly_disconnected, still_to_disconnect = hosts_to_disconnect.partition(&:try_disconnect) gentle_disconnected_hosts.concat(newly_disconnected) hosts_to_disconnect = still_to_disconnect @@ -283,7 +282,7 @@ def disconnect_old_hosts(hosts) formatted_all_hosts = formatted_gentle_hosts + formatted_forced_hosts - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :host_list_disconnection, message: "Disconnected #{formatted_all_hosts} old load balancing hosts after #{total_disconnect_duration}s", gentle_disconnected_hosts: formatted_gentle_hosts, diff --git a/lib/gitlab/database/load_balancing/service_discovery/sampler.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb similarity index 93% rename from lib/gitlab/database/load_balancing/service_discovery/sampler.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb index bb0508cc9b622e..cbc6bfd0bc579a 100644 --- a/lib/gitlab/database/load_balancing/service_discovery/sampler.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb @@ -16,7 +16,7 @@ def initialize(max_replica_pools:, seed: Random.new_seed) def sample(addresses) return addresses if @max_replica_pools.nil? || addresses.count <= @max_replica_pools - ::Gitlab::Database::LoadBalancing::Logger.debug( + ::Gitlab::Database::LoadBalancing::Callbacks.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, @@ -37,7 +37,7 @@ def sample(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| + addresses_by_host.each do |_host, addresses| next if addresses.empty? selected_addresses << addresses.pop diff --git a/lib/gitlab/database/load_balancing/session.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session.rb similarity index 100% rename from lib/gitlab/database/load_balancing/session.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session.rb diff --git a/lib/gitlab/database/load_balancing/setup.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb similarity index 94% rename from lib/gitlab/database/load_balancing/setup.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb index 2e65e1c8e56fae..d5be4800c6d7f1 100644 --- a/lib/gitlab/database/load_balancing/setup.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb @@ -18,7 +18,7 @@ def setup setup_connection_proxy setup_service_discovery - ::Gitlab::Database::LoadBalancing::Logger.debug( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.debug( event: :setup, model: model.name, start_service_discovery: @start_service_discovery @@ -30,7 +30,7 @@ def configure_connection hash = db_config_object.configuration_hash.merge( prepared_statements: false, - pool: Gitlab::Database.default_pool_size + pool: Gitlab::Database::LoadBalancing.default_pool_size ) hash_config = ActiveRecord::DatabaseConfigurations::HashConfig.new( diff --git a/lib/gitlab/database/load_balancing/srv_resolver.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/srv_resolver.rb similarity index 84% rename from lib/gitlab/database/load_balancing/srv_resolver.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/srv_resolver.rb index 1f599ef4a273f9..312c95dd0283e5 100644 --- a/lib/gitlab/database/load_balancing/srv_resolver.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/srv_resolver.rb @@ -28,12 +28,11 @@ def address_for(host) private def addresses_from_additional - strong_memoize(:addresses_from_additional) do - additional.each_with_object({}) do |rr, h| - h[rr.name] = rr.address if rr.is_a?(Net::DNS::RR::A) || rr.is_a?(Net::DNS::RR::AAAA) - end + additional.each_with_object({}) do |rr, h| + h[rr.name] = rr.address if rr.is_a?(Net::DNS::RR::A) || rr.is_a?(Net::DNS::RR::AAAA) end end + strong_memoize_attr :addresses_from_additional def resolve_host(host) record = resolver.search(host, Net::DNS::ANY).answer.find do |rr| diff --git a/lib/gitlab/database/load_balancing/sticking.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb similarity index 91% rename from lib/gitlab/database/load_balancing/sticking.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb index 8260893f0dd468..3c3a362bb168f7 100644 --- a/lib/gitlab/database/load_balancing/sticking.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb @@ -95,21 +95,15 @@ def with_primary_write_location end def unstick(namespace, id) - with_redis do |redis| - redis.del(redis_key_for(namespace, id)) - end + Callbacks.del_wal_for(redis_key_for(namespace, id)) end def set_write_location_for(namespace, id, location) - with_redis do |redis| - redis.set(redis_key_for(namespace, id), location, ex: EXPIRATION) - end + Callbacks.set_wal_for(redis_key_for(namespace, id), location, ex: EXPIRATION) end def last_write_location_for(namespace, id) - with_redis do |redis| - redis.get(redis_key_for(namespace, id)) - end + Callbacks.get_wal_for(redis_key_for(namespace, id)) end def redis_key_for(namespace, id) @@ -118,10 +112,6 @@ def redis_key_for(namespace, id) "database-load-balancing/write-location/#{name}/#{namespace}/#{id}" end - def with_redis(&block) - Gitlab::Redis::DbLoadBalancing.with(&block) - end - def use_primary! ::Gitlab::Database::LoadBalancing::SessionMap.current(@load_balancer).use_primary! end diff --git a/spec/fixtures/dns/a_rr.json b/gems/gitlab-database-load_balancing/spec/fixtures/dns/a_rr.json similarity index 100% rename from spec/fixtures/dns/a_rr.json rename to gems/gitlab-database-load_balancing/spec/fixtures/dns/a_rr.json diff --git a/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json b/gems/gitlab-database-load_balancing/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json similarity index 100% rename from spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json rename to gems/gitlab-database-load_balancing/spec/fixtures/dns/a_with_aaaa_rr_in_additional_section.json diff --git a/spec/fixtures/dns/aaaa_rr.json b/gems/gitlab-database-load_balancing/spec/fixtures/dns/aaaa_rr.json similarity index 100% rename from spec/fixtures/dns/aaaa_rr.json rename to gems/gitlab-database-load_balancing/spec/fixtures/dns/aaaa_rr.json diff --git a/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json b/gems/gitlab-database-load_balancing/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json similarity index 100% rename from spec/fixtures/dns/srv_with_a_rr_in_additional_section.json rename to gems/gitlab-database-load_balancing/spec/fixtures/dns/srv_with_a_rr_in_additional_section.json diff --git a/spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/action_cable_callbacks_spec.rb similarity index 100% rename from spec/lib/gitlab/database/load_balancing/action_cable_callbacks_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/action_cable_callbacks_spec.rb diff --git a/spec/lib/gitlab/database/load_balancing/configuration_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb similarity index 94% rename from spec/lib/gitlab/database/load_balancing/configuration_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb index 7dc2e0be3e5e90..41534c17c06293 100644 --- a/spec/lib/gitlab/database/load_balancing/configuration_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb @@ -26,7 +26,7 @@ use_tcp: false, max_replica_pools: nil ) - expect(config.pool_size).to eq(Gitlab::Database.default_pool_size) + expect(config.pool_size).to eq(Gitlab::Database::LoadBalancing.default_pool_size) end end @@ -110,7 +110,7 @@ it 'returns false when running inside a Rake task' do config = described_class.new(ActiveRecord::Base, %w[foo bar]) - allow(Gitlab::Runtime).to receive(:rake?).and_return(true) + allow(Gitlab::Database::LoadBalancing).to receive(:enabled).and_return(false) expect(config.load_balancing_enabled?).to eq(false) end @@ -137,7 +137,7 @@ describe '#service_discovery_enabled?' do it 'returns false when running inside a Rake task' do - allow(Gitlab::Runtime).to receive(:rake?).and_return(true) + allow(Gitlab::Database::LoadBalancing).to receive(:enabled).and_return(false) config = described_class.new(ActiveRecord::Base) config.service_discovery[:record] = 'foo' @@ -184,7 +184,7 @@ it 'returns the default pool size' do config = described_class.new(model) - expect(config.pool_size).to eq(Gitlab::Database.default_pool_size) + expect(config.pool_size).to eq(Gitlab::Database::LoadBalancing.default_pool_size) end end end diff --git a/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb similarity index 97% rename from spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb index 4d41fa5d7c6138..7ee9d6114cc07c 100644 --- a/spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb @@ -16,7 +16,7 @@ end describe '#select_all' do - let(:override_proxy) { ActiveRecord::Base.connection.class } + let(:override_proxy) { ApplicationRecord.connection.class } # We can't use :Gitlab::Utils::Override because this method is dynamically prepended it 'method signatures match' do @@ -141,7 +141,7 @@ .to receive(:current).with(load_balancer).and_return(session) end - context 'session fallbacks ambiguous queries to replicas' do + context 'when session fallbacks ambiguous queries to replicas' do let(:replica) { double(:connection) } before do @@ -174,7 +174,7 @@ end end - context 'session does not fallback to replicas for ambiguous queries' do + context 'when session does not fallback to replicas for ambiguous queries' do let(:primary) { double(:connection) } before do @@ -227,7 +227,7 @@ .not_to raise_error end - context 'current session prefers to fallback ambiguous queries to replicas' do + context 'when current session prefers to fallback ambiguous queries to replicas' do let(:session) { double(:session) } before do diff --git a/spec/lib/gitlab/database/load_balancing/host_list_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb similarity index 93% rename from spec/lib/gitlab/database/load_balancing/host_list_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb index 61183f5a99cd1c..0f4e21bb6d5e48 100644 --- a/spec/lib/gitlab/database/load_balancing/host_list_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb @@ -19,6 +19,8 @@ allow(load_balancer).to receive(:create_replica_connection_pool) do double(:replica_connection_pool) end + + allow(Gitlab::Database::LoadBalancing::Callbacks).to receive(:metrics_host_gauge) end describe '#initialize' do @@ -136,6 +138,8 @@ end def expect_metrics(hosts) - expect(Gitlab::Metrics.client.get(:db_load_balancing_hosts).get({})).to eq(hosts) + expect(Gitlab::Database::LoadBalancing::Callbacks).to have_received(:metrics_host_gauge) + .with({}, hosts) + .at_least(1).times end end diff --git a/spec/lib/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb similarity index 96% rename from spec/lib/gitlab/database/load_balancing/host_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index ec94485f258f06..9eff5d1f2d3d48 100644 --- a/spec/lib/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -89,7 +89,7 @@ def wrapped_exception(wrapper, original) it 'marks the host as offline' do expect(host.pool).to receive(:disconnect!) - expect(Gitlab::Database::LoadBalancing::Logger).to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:warn) .with(hash_including(event: :host_offline)) .and_call_original @@ -105,8 +105,8 @@ def wrapped_exception(wrapper, original) it 'returns the latest status' do expect(host).not_to receive(:refresh_status) - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:info) - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:info) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:warn) expect(host).to be_online end @@ -115,8 +115,8 @@ def wrapped_exception(wrapper, original) host.offline! expect(host).not_to receive(:refresh_status) - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:info) - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:info) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:warn) expect(host).not_to be_online end @@ -137,7 +137,7 @@ def wrapped_exception(wrapper, original) # Hosts are online by default it 'does not log the online event' do - expect(Gitlab::Database::LoadBalancing::Logger) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger) .not_to receive(:info) .with(hash_including(event: :host_online)) @@ -151,7 +151,7 @@ def wrapped_exception(wrapper, original) end it 'logs the online event' do - expect(Gitlab::Database::LoadBalancing::Logger) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger) .to receive(:info) .with(hash_including(event: :host_online)) .and_call_original @@ -166,7 +166,7 @@ def wrapped_exception(wrapper, original) end it 'marks the host offline' do - expect(Gitlab::Database::LoadBalancing::Logger).to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:warn) .with(hash_including(event: :host_offline)) .and_call_original diff --git a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb similarity index 98% rename from spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb index 3c14dc23a8083a..24bdb7ee6f1a93 100644 --- a/spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb @@ -191,7 +191,7 @@ def twice_wrapped_exception(top, middle, original) lb.read { raise conflict_error } end - context 'only primary is configured' do + context 'when only primary is configured' do let(:lb) do config = Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base) allow(config).to receive(:load_balancing_enabled?).and_return(false) @@ -230,7 +230,7 @@ def twice_wrapped_exception(top, middle, original) # When no hosts are configured, we don't want to produce any warnings, as # they aren't useful/too noisy. - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:warn) expect { |b| lb.read(&b) } .to yield_with_args(ActiveRecord::Base.retrieve_connection) @@ -594,7 +594,11 @@ def with_replica_pool(*args) it 'returns the diff between two write locations' do loc1 = lb.send(:get_write_location, lb.pool.connection) - create(:user) # This ensures we get a new WAL location + ActiveRecord::Schema.define do + create_table :_test_load_balancing_test, force: true do |t| + t.string :name, null: true + end + end loc2 = lb.send(:get_write_location, lb.pool.connection) diff = lb.wal_diff(loc2, loc1) diff --git a/spec/lib/gitlab/database/load_balancing/primary_host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb similarity index 96% rename from spec/lib/gitlab/database/load_balancing/primary_host_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb index 53605d14c1726d..d1e1b3eda46106 100644 --- a/spec/lib/gitlab/database/load_balancing/primary_host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb @@ -52,7 +52,7 @@ describe '#offline!' do it 'logs the event but does nothing else' do - expect(Gitlab::Database::LoadBalancing::Logger).to receive(:warn) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:warn) .with(hash_including(event: :host_offline)) .and_call_original diff --git a/spec/lib/gitlab/database/load_balancing/resolver_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb similarity index 100% rename from spec/lib/gitlab/database/load_balancing/resolver_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb diff --git a/spec/lib/gitlab/database/load_balancing/service_discovery/sampler_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery/sampler_spec.rb similarity index 93% rename from spec/lib/gitlab/database/load_balancing/service_discovery/sampler_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery/sampler_spec.rb index 9aa263524b14d4..b29ea1bc46c779 100644 --- a/spec/lib/gitlab/database/load_balancing/service_discovery/sampler_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery/sampler_spec.rb @@ -27,8 +27,8 @@ it 'samples random ports across all hosts' do expect(sampler.sample(addresses)).to eq([ address_class.new("127.0.0.1", 6432), - address_class.new("127.0.0.2", 6435), - address_class.new("127.0.0.1", 6435) + address_class.new("127.0.0.2", 6435), + address_class.new("127.0.0.1", 6435) ]) end diff --git a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb similarity index 96% rename from spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb index 4d35e16a865139..bf6139950f247a 100644 --- a/spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb @@ -88,7 +88,7 @@ expect(service).not_to receive(:sleep) - expect(Gitlab::ErrorTracking).not_to receive(:track_exception) + expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:track_exception) service.perform_service_discovery end @@ -96,7 +96,7 @@ context 'with StandardError' do before do - allow(Gitlab::ErrorTracking).to receive(:track_exception) + allow(Gitlab::Database::LoadBalancing::Callbacks).to receive(:track_exception) allow(service).to receive(:sleep) end @@ -139,7 +139,7 @@ .to receive(:refresh_if_necessary) .and_raise(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times - expect(Gitlab::ErrorTracking) + expect(Gitlab::Database::LoadBalancing::Callbacks) .to receive(:track_exception) .with(error).exactly(described_class::MAX_DISCOVERY_RETRIES).times @@ -251,7 +251,7 @@ end it 'does not log any load balancing event' do - expect(::Gitlab::Database::LoadBalancing::Logger).not_to receive(:info) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:info) service.replace_hosts([address_foo, address_bar]) end @@ -460,7 +460,7 @@ it 'does not log any interruption' do expect(service.refresh_thread_last_run).to be_nil - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:error) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) subject end @@ -470,7 +470,7 @@ let(:last_run_timestamp) { Time.current } it 'does not log if last run time plus delta is in future' do - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:error) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) subject end @@ -482,7 +482,7 @@ it 'does not log if the interruption is already logged' do service.refresh_thread_interruption_logged = true - expect(Gitlab::Database::LoadBalancing::Logger).not_to receive(:error) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) subject end @@ -490,7 +490,7 @@ it 'logs the error if the interruption was not logged before' do expect(service.refresh_thread_interruption_logged).not_to be_present - expect(Gitlab::Database::LoadBalancing::Logger).to receive(:error).with( + expect(Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:error).with( event: :service_discovery_refresh_thread_interrupt, refresh_thread_last_run: last_run_timestamp, thread_status: refresh_thread.status.to_s, diff --git a/spec/lib/gitlab/database/load_balancing/session_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb similarity index 100% rename from spec/lib/gitlab/database/load_balancing/session_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb diff --git a/spec/lib/gitlab/database/load_balancing/setup_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb similarity index 97% rename from spec/lib/gitlab/database/load_balancing/setup_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb index fa6d71bca7fab9..2e62dd0f95d443 100644 --- a/spec/lib/gitlab/database/load_balancing/setup_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb @@ -30,7 +30,7 @@ .with('test', 'main', { host: 'localhost', prepared_statements: false, - pool: Gitlab::Database.default_pool_size + pool: Gitlab::Database::LoadBalancing.default_pool_size }) .and_call_original @@ -119,7 +119,7 @@ end end - context 'uses correct base models', :reestablished_active_record_base do + context 'when using correct base models', :reestablished_active_record_base do using RSpec::Parameterized::TableSyntax let(:ci_class) do diff --git a/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb similarity index 91% rename from spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb index 6ac0608d4851de..27c8a0b7c26420 100644 --- a/spec/lib/gitlab/database/load_balancing/srv_resolver_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb @@ -52,8 +52,9 @@ end def dns_response_packet_from_fixture(fixture_name) - fixture = File.read(Rails.root + "spec/fixtures/dns/#{fixture_name}.json") - encoded_payload = Gitlab::Json.parse(fixture)['payload'] + path = File.join(File.dirname(__FILE__), "../../../fixtures/dns/#{fixture_name}.json") + fixture = File.read(path) + encoded_payload = JSON.parse(fixture)['payload'] payload = Base64.decode64(encoded_payload) Net::DNS::Packet.parse(payload) diff --git a/spec/lib/gitlab/database/load_balancing/sticking_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb similarity index 92% rename from spec/lib/gitlab/database/load_balancing/sticking_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb index 5462778fd62dd3..699ffdb3e21682 100644 --- a/spec/lib/gitlab/database/load_balancing/sticking_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb @@ -13,17 +13,14 @@ described_class.new(load_balancer) end - let(:redis) { instance_double(::Gitlab::Redis::MultiStore) } - before do Gitlab::Database::LoadBalancing::SessionMap.clear_session - allow(::Gitlab::Redis::DbLoadBalancing).to receive(:with).and_yield(redis) allow(ActiveRecord::Base.load_balancer) .to receive(:primary_write_location) .and_return(primary_write_location) - allow(redis).to receive(:get) + allow(Gitlab::Database::LoadBalancing::Callbacks).to receive(:get_wal_for) .with("database-load-balancing/write-location/#{load_balancer.name}/user/42") .and_return(last_write_location) end @@ -50,7 +47,7 @@ it 'returns false, does not unstick and calls use_primary!' do expect(load_balancer).not_to receive(:select_up_to_date_host) - expect(redis).not_to receive(:del) + expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).to receive(:use_primary!) expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_empty_location: true)).to eq(false) @@ -63,8 +60,7 @@ expect(load_balancer).to receive(:select_up_to_date_host).with(last_write_location) .and_return(::Gitlab::Database::LoadBalancing::LoadBalancer::ALL_CAUGHT_UP) - expect(redis) - .to receive(:del) + expect(Gitlab::Database::LoadBalancing::Callbacks).to receive(:del_wal_for) .with("database-load-balancing/write-location/#{load_balancer.name}/user/42") expect(sticking.find_caught_up_replica(:user, 42)).to eq(true) @@ -76,7 +72,7 @@ expect(load_balancer).to receive(:select_up_to_date_host).with(last_write_location) .and_return(::Gitlab::Database::LoadBalancing::LoadBalancer::ANY_CAUGHT_UP) - expect(redis).not_to receive(:del) + expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(sticking.find_caught_up_replica(:user, 42)).to eq(true) end @@ -89,7 +85,7 @@ end it 'returns false, does not unstick and calls use_primary!' do - expect(redis).not_to receive(:del) + expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).to receive(:use_primary!) expect(sticking.find_caught_up_replica(:user, 42)).to eq(false) @@ -97,7 +93,7 @@ context 'when use_primary_on_failure is false' do it 'does not call use_primary!' do - expect(redis).not_to receive(:del) + expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).not_to receive(:use_primary!) expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_failure: false)).to eq(false) @@ -113,8 +109,7 @@ .and_return(false) ids.each do |id| - expect(redis) - .to receive(:set) + expect(Gitlab::Database::LoadBalancing::Callbacks).to receive(:set_wal_for) .with("database-load-balancing/write-location/#{load_balancer.name}/user/#{id}", 'the-primary-lsn', ex: 30) end diff --git a/spec/lib/gitlab/database/load_balancing/transaction_leaking_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/transaction_leaking_spec.rb similarity index 89% rename from spec/lib/gitlab/database/load_balancing/transaction_leaking_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/transaction_leaking_spec.rb index 76eb473c07bcad..16a09912df823b 100644 --- a/spec/lib/gitlab/database/load_balancing/transaction_leaking_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/transaction_leaking_spec.rb @@ -17,7 +17,7 @@ Gitlab::Database::LoadBalancing::Setup.new(model).setup - model.connection.execute(<<~SQL) + model.connection.execute(<<~SQL.squish) CREATE TABLE IF NOT EXISTS #{test_table_name} (id SERIAL PRIMARY KEY, value INTEGER) SQL @@ -27,7 +27,7 @@ end after do - model.connection.execute(<<~SQL) + model.connection.execute(<<~SQL.squish) DROP TABLE IF EXISTS #{test_table_name} SQL @@ -43,7 +43,7 @@ def execute(conn) # This will result in a PG error, which is not raised. # Instead, we retry the statement on a fresh connection (where the pid is different and it does nothing) # and the load balancer continues with a fresh connection and no transaction if a transaction was open previously - conn.execute(<<~SQL) + conn.execute(<<~SQL.squish) SELECT CASE WHEN pg_backend_pid() = #{backend_pid} THEN pg_terminate_backend(#{backend_pid}) @@ -57,7 +57,7 @@ def execute(conn) context 'in a transaction' do it 'raises an exception when a retry would occur' do - expect(::Gitlab::Database::LoadBalancing::Logger) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger) .not_to receive(:warn).with(hash_including(event: :transaction_leak)) expect do @@ -70,9 +70,9 @@ def execute(conn) context 'without a transaction' do it 'retries' do - expect(::Gitlab::Database::LoadBalancing::Logger) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger) .not_to receive(:warn).with(hash_including(event: :transaction_leak)) - expect(::Gitlab::Database::LoadBalancing::Logger) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger) .to receive(:warn).with(hash_including(event: :read_write_retry)) expect { execute(model.connection) }.not_to raise_error diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index 71faf49cce0c78..c60e502291be6f 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -8,6 +8,11 @@ require 'gitlab/utils/all' require 'gitlab/safe_request_store' +require "gitlab/database/load_balancing" + +require_relative 'support/database_replica' +require_relative 'support/application_record' + RSpec.configure do |config| include StubRails include NextInstanceOf @@ -25,4 +30,13 @@ config.around(:example, :request_store) do |example| ::Gitlab::SafeRequestStore.ensure_request_store { example.run } end + + config.before(:all) do + Gitlab::Database::LoadBalancing.default_pool_size = 20 + Gitlab::Database::LoadBalancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] + + Gitlab::Database::LoadBalancing.base_models.each do |model| + Gitlab::Database::LoadBalancing::Setup.new(model).setup + end + end end diff --git a/gems/gitlab-database-load_balancing/spec/support/application_record.rb b/gems/gitlab-database-load_balancing/spec/support/application_record.rb new file mode 100644 index 00000000000000..acea00b5072cc1 --- /dev/null +++ b/gems/gitlab-database-load_balancing/spec/support/application_record.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end + +module Ci + class ApplicationRecord < ApplicationRecord + self.abstract_class = true + end +end diff --git a/gems/gitlab-database-load_balancing/spec/support/database_replica.rb b/gems/gitlab-database-load_balancing/spec/support/database_replica.rb new file mode 100644 index 00000000000000..b37540105a8e10 --- /dev/null +++ b/gems/gitlab-database-load_balancing/spec/support/database_replica.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +RSpec.configure do |config| + config.around(:each, :database_replica) do |example| + old_proxies = {} + + Gitlab::Database::LoadBalancing.base_models.each do |model| + old_proxies[model] = [model.load_balancer, model.connection, model.sticking] + + config = Gitlab::Database::LoadBalancing::Configuration + .new(model, [model.connection_db_config.configuration_hash[:host]]) + + model.load_balancer = Gitlab::Database::LoadBalancing::LoadBalancer.new(config) + model.sticking = Gitlab::Database::LoadBalancing::Sticking.new(model.load_balancer) + model.connection = Gitlab::Database::LoadBalancing::ConnectionProxy.new(model.load_balancer) + end + + Gitlab::Database::LoadBalancing::Session.clear_session + + example.run + + Gitlab::Database::LoadBalancing::Session.clear_session + + old_proxies.each do |model, proxy| + model.load_balancer, model.connection, model.sticking = proxy + end + end +end diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 5d347f954d90bf..3c8cc7b5287a72 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'gitlab/database/load_balancing' + module Gitlab module Database MAIN_DATABASE_NAME = 'main' @@ -298,27 +300,7 @@ def self.gitlab_schemas_for_connection(connection) end def self.db_config_for_connection(connection) - return unless connection - - # For a ConnectionProxy we want to avoid ambiguous db_config as it may - # sometimes default to replica so we always return the primary config - # instead. - if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy) - return connection.load_balancer.configuration.db_config - end - - # During application init we might receive `NullPool` - return unless connection.respond_to?(:pool) && - connection.pool.respond_to?(:db_config) - - db_config = connection.pool.db_config - db_config unless empty_config?(db_config) - end - - def self.empty_config?(db_config) - return true unless db_config - - db_config.is_a?(ActiveRecord::ConnectionAdapters::NullPool::NullConfig) + Gitlab::Database::LoadBalancing.db_config_for_connection(connection) end # At the moment, the connection can only be retrieved by -- GitLab From 6adbb11a1a8c89e392dee2be800996cacb1cee6c Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Mon, 21 Jul 2025 11:25:27 -0500 Subject: [PATCH 05/31] Add load balancer Gemfile.next checksums --- .../Gemfile.next.lock | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/gems/gitlab-database-load_balancing/Gemfile.next.lock b/gems/gitlab-database-load_balancing/Gemfile.next.lock index 4ecad0a049ba19..73660a0525d681 100644 --- a/gems/gitlab-database-load_balancing/Gemfile.next.lock +++ b/gems/gitlab-database-load_balancing/Gemfile.next.lock @@ -352,5 +352,119 @@ DEPENDENCIES rubocop (~> 1.71.1) rubocop-rspec (~> 3.0.4) +CHECKSUMS + actioncable (7.2.2.1) sha256=5b3b885075a80767d63cbf2b586cbf82466a241675b7985233f957abb01bffb4 + actionmailbox (7.2.2.1) sha256=896a47c2520f4507c75dde67c6ea1f5eec3a041fe7bfbf3568c4e0149a080e25 + actionmailer (7.2.2.1) sha256=b02ae523c32c8ad762d4db941e76f3c108c106030132247ee7a7b8c86bc7b21f + actionpack (7.2.2.1) sha256=17b2160a7bcbd5a569d06b1ae54a4bb5ccc7ba0815d73ff5768100a79dc1f734 + actiontext (7.2.2.1) sha256=f369cee41a6674b697bf9257d917a3dce575a2c89935af437b432d6737a3f0d6 + actionview (7.2.2.1) sha256=69fc880cf3d8b1baf21b048cf7bb68f1eef08760ff8104d7d60a6a1be8b359a5 + activejob (7.2.2.1) sha256=f2f95a8573b394aa4f7c24843f0c4a6065c073a5c64d6f15ecd98d98c2c23e5b + activemodel (7.2.2.1) sha256=8398861f9ee2c4671a8357ab39e9b38a045fd656f6685a3dd5890c2419dbfdaf + activerecord (7.2.2.1) sha256=79a31f71c32d5138717c2104e0ff105f5d82922247c85bdca144f2720e67fab9 + activerecord-gitlab (0.2.0) + activestorage (7.2.2.1) sha256=b4ec35ff94d4d6656ee6952ce439c3f80e249552d49fd2d3996ee53880c5525f + activesupport (7.2.2.1) sha256=842bcbf8a92977f80fb4750661a237cf5dd4fdd442066b3c35e88afb488647f5 + addressable (2.8.7) sha256=462986537cf3735ab5f3c0f557f14155d778f4b43ea4f485a9deb9c8f7c58232 + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + benchmark (0.4.1) sha256=d4ef40037bba27f03b28013e219b950b82bace296549ec15a78016552f8d2cce + bigdecimal (3.2.2) sha256=39085f76b495eb39a79ce07af716f3a6829bc35eb44f2195e2753749f2fa5adc + binding_of_caller (1.0.1) sha256=2b2902abff4246ddcfbc4da9b69bc4a019e22aeb300c2ff6289a173d4b90b29a + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b + concurrent-ruby (1.3.5) sha256=813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6 + connection_pool (2.5.3) sha256=cfd74a82b9b094d1ce30c4f1a346da23ee19dc8a062a16a85f58eab1ced4305b + crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d + date (3.4.1) sha256=bf268e14ef7158009bfeaec40b5fa3c7271906e88b196d958a89d4b408abe64f + debug_inspector (1.2.0) sha256=9bdfa02eebc3da163833e6a89b154084232f5766087e59573b70521c77ea68a2 + diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + erb (5.0.2) sha256=d30f258143d4300fb4ecf430042ac12970c9bb4b33c974a545b8f58c1ec26c0f + erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9 + gitlab-database-load_balancing (0.1.0) + gitlab-net-dns (0.15.0) sha256=d229aae205055b86b2ad166981257eb589ce6d6a146aa79b3ea2b1e5d9741f46 + gitlab-rspec (0.1.0) + gitlab-safe_request_store (0.1.0) + gitlab-styles (10.1.0) sha256=f42745f5397d042fe24cf2d0eb56c995b37f9f43d8fb79b834d197a1cafdc84a + gitlab-utils (0.1.0) + globalid (1.2.1) sha256=70bf76711871f843dbba72beb8613229a49429d1866828476f9c9d6ccc327ce9 + i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f + io-console (0.8.1) sha256=1e15440a6b2f67b6ea496df7c474ed62c860ad11237f29b3bd187f054b925fcb + irb (1.15.2) sha256=222f32952e278da34b58ffe45e8634bf4afc2dc7aa9da23fed67e581aa50fdba + json (2.12.2) sha256=ba94a48ad265605c8fa9a50a5892f3ba6a02661aa010f638211f3cb36f44abf4 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + loofah (2.24.1) sha256=655a30842b70ec476410b347ab1cd2a5b92da46a19044357bbd9f401b009a337 + mail (2.8.1) sha256=ec3b9fadcf2b3755c78785cb17bc9a0ca9ee9857108a64b6f5cfc9c0b5bfc9ad + marcel (1.0.4) sha256=0d5649feb64b8f19f3d3468b96c680bae9746335d02194270287868a661516a4 + method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5 + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + mini_portile2 (2.8.9) sha256=0cd7c7f824e010c072e33f68bc02d85a00aeb6fce05bb4819c03dfd3c140c289 + minitest (5.25.5) sha256=391b6c6cb43a4802bfb7c93af1ebe2ac66a210293f4a3fb7db36f2fc7dc2c756 + net-imap (0.5.9) sha256=d95905321e1bd9f294ffc7ff8697be218eee1ec96c8504c0960964d0a0be33fc + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + nio4r (2.7.4) sha256=d95dee68e0bb251b8ff90ac3423a511e3b784124e5db7ff5f4813a220ae73ca9 + nokogiri (1.18.8) sha256=8c7464875d9ca7f71080c24c0db7bcaa3940e8be3c6fc4bcebccf8b9a0016365 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parser (3.3.8.0) sha256=2476364142b307fa5a1b1ece44f260728be23858a9c71078e956131a75453c45 + pg (1.5.9) sha256=761efbdf73b66516f0c26fcbe6515dc7500c3f0aa1a1b853feae245433c64fdc + pp (0.6.2) sha256=947ec3120c6f92195f8ee8aa25a7b2c5297bb106d83b41baa02983686577b6ff + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.4.0) sha256=dc0e3e00e93160213dc2a65519d9002a4a1e7b962db57d444cf1a71565bb703e + proc_to_ast (0.2.0) sha256=4bb446419c3878c21d8792f8a129616690168f636b9e460b5a0ed26dd6680bbe + pry (0.15.2) sha256=12d54b8640d3fa29c9211dd4ffb08f3fd8bf7a4fd9b5a73ce5b59c8709385b6b + psych (5.2.6) sha256=814328aa5dcb6d604d32126a20bc1cbcf05521a5b49dbb1a8b30a07e580f316e + public_suffix (6.0.2) sha256=bfa7cd5108066f8c9602e0d6d4114999a5df5839a63149d3e8b0f9c1d3558394 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (2.2.17) sha256=5fe02a1ca80d6fb2271dba00985ee2962d6f5620b6f46dfed89f5301ac4699dd + rack-session (1.0.2) sha256=a02115e5420b4de036839b9811e3f7967d73446a554b42aa45106af335851d76 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rackup (1.0.1) sha256=ba86604a28989fe1043bff20d819b360944ca08156406812dca6742b24b3c249 + rails (7.2.2.1) sha256=aedb1604b40f4e43b5e8066e5a1aa34dae02c33aa9669b21fd4497d0f8c9bb40 + rails-dom-testing (2.3.0) sha256=8acc7953a7b911ca44588bf08737bc16719f431a1cc3091a292bca7317925c1d + rails-html-sanitizer (1.6.2) sha256=35fce2ca8242da8775c83b6ba9c1bcaad6751d9eb73c1abaa8403475ab89a560 + railties (7.2.2.1) sha256=e3f11bf116dd6d0d874522843ccc70ec0f89fbfed3e9c2ee48a4778cd042fe1f + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.3.0) sha256=96f5092d786ff412c62fde76f793cc0541bd84d2eb579caa529aa8a059934493 + rdoc (6.14.2) sha256=9fdd44df130f856ae70cc9a264dfd659b9b40de369b16581f4ab746e42439226 + regexp_parser (2.10.0) sha256=cb6f0ddde88772cd64bff1dbbf68df66d376043fe2e66a9ef77fcb1b0c548c61 + reline (0.6.1) sha256=1afcc9d7cb1029cdbe780d72f2f09251ce46d3780050f3ec39c3ccc6b60675fb + request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb + rexml (3.4.1) sha256=c74527a9a0a04b4ec31dbe0dc4ed6004b960af943d8db42e539edde3a871abca + rouge (4.5.2) sha256=034233fb8a69d0ad0e0476943184e04cb971b68e3c2239724e02f428878b68a3 + rspec (3.13.1) sha256=b9f9a58fa915b8d94a1d6b3195fe6dd28c4c34836a6097015142c4a9ace72140 + rspec-core (3.13.5) sha256=ab3f682897c6131c67f9a17cfee5022a597f283aebe654d329a565f9937a4fa3 + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.5) sha256=e4338a6f285ada9fe56f5893f5457783af8194f5d08884d17a87321d5195ea81 + rspec-parameterized (1.0.2) sha256=b456dec0091924175ac13963e173cdbaa2ab3e1581a405a948addc34e3f3f4c2 + rspec-parameterized-core (1.0.1) sha256=31819939c433f58b59f83d1bcd08697ca74ea7e44e2a207f7445934f88461aab + rspec-parameterized-table_syntax (1.0.1) sha256=ffead8f21f0711b3cdf8b74386f2ef7ac93b39c40b60658a5eda97072580f2fc + rspec-rails (6.0.4) sha256=60bbfd7ec06124d0cd3eedcdf1ce31b6faa58bfdd0413ccbadd9db84a168ae0d + rspec-support (3.13.4) sha256=184b1814f6a968102b57df631892c7f1990a91c9a3b9e80ef892a0fc2a71a3f7 + rubocop (1.50.2) sha256=7cfeb0616f686ac61d049beae89f31446792d7e9f5728152657548f70aa78650 + rubocop-ast (1.46.0) sha256=0da7f6ad5b98614f89b74f11873c191059c823eae07d6ffd40a42a3338f2232b + rubocop-capybara (2.21.0) sha256=5d264efdd8b6c7081a3d4889decf1451a1cfaaec204d81534e236bc825b280ab + rubocop-factory_bot (2.26.0) sha256=17593a8dd296867c906a33946d91e69232c9a3084c92933f5109d23e0451a37f + rubocop-graphql (0.19.0) sha256=ba4b2fc91c9f0fda47e0870a6ae15a1e5525d6caffcb150dc88b00caaacc3e43 + rubocop-performance (1.23.1) sha256=f22f86a795f5e6a6180aac2c6fc172534b173a068d6ed3396d6460523e051b82 + rubocop-rails (2.25.1) sha256=4988933ee02fdb213d22d0f61dc57d6c582317b43867d5106ea1c7a628aae6a5 + rubocop-rspec (2.31.0) sha256=2bae19388d78e1ceace44cd95fd34f3209f4ef20cac1b168d0a1325cbba3d672 + rubocop-rspec_rails (2.29.0) sha256=31911e8a2de980394b707e0861f306666c22bb9cbec0a63917a5a178c21a31a1 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + stringio (3.1.7) sha256=5b78b7cb242a315fb4fca61a8255d62ec438f58da2b90be66048546ade4507fa + thor (1.3.2) sha256=eef0293b9e24158ccad7ab383ae83534b7ad4ed99c09f96f1a6b036550abbeda + timeout (0.4.3) sha256=9509f079b2b55fe4236d79633bd75e34c1c1e7e3fb4b56cb5fda61f80a0fe30e + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + unparser (0.8.0) sha256=7e199512cfdf7683d51a5060d4668988f6c5659a0904f5fae89a55b3cbd548c1 + useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844 + webrick (1.9.1) sha256=b42d3c94f166f3fb73d87e9b359def9b5836c426fc8beacf38f2184a21b2a989 + websocket-driver (0.8.0) sha256=ed0dba4b943c22f17f9a734817e808bc84cdce6a7e22045f5315aa57676d4962 + websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 + zeitwerk (2.7.3) sha256=b2e86b4a9b57d26ba68a15230dcc7fe6f040f06831ce64417b0621ad96ba3e85 + BUNDLED WITH 2.6.9 -- GitLab From fc31dffa526ada1d2e57658443cc0ac0d2164244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 22 Nov 2023 10:52:42 +0100 Subject: [PATCH 06/31] Move `spec/gitlab/database/load_balancing_spec.rb` --- .../spec}/gitlab/database/load_balancing_spec.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing_spec.rb (100%) diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb similarity index 100% rename from spec/lib/gitlab/database/load_balancing_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb -- GitLab From 4392c7800033c7912e175b311892fd0d8f4b560f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 22 Nov 2023 10:58:40 +0100 Subject: [PATCH 07/31] Move some LB specs to initializer specs --- .../gitlab/database/load_balancing_spec.rb | 16 ---------------- spec/initializers/load_balancing_spec.rb | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb index 92682896fac25f..2c4536223c5a72 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb @@ -3,22 +3,6 @@ require 'spec_helper' RSpec.describe Gitlab::Database::LoadBalancing, :suppress_gitlab_schemas_validate_connection, feature_category: :database do - describe '.base_models' do - it 'returns the models to apply load balancing to' do - models = described_class.base_models - - expect(models).to include(ActiveRecord::Base) - - if Gitlab::Database.has_config?(:ci) - expect(models).to include(Ci::ApplicationRecord) - end - end - - it 'returns the models as a frozen array' do - expect(described_class.base_models).to be_frozen - end - end - describe '.each_load_balancer' do it 'yields every load balancer to the supplied block' do lbs = [] diff --git a/spec/initializers/load_balancing_spec.rb b/spec/initializers/load_balancing_spec.rb index 9b7459bd2fcaa3..0f64469615fc61 100644 --- a/spec/initializers/load_balancing_spec.rb +++ b/spec/initializers/load_balancing_spec.rb @@ -97,4 +97,22 @@ def simulate_puma_worker end end end + + describe Gitlab::Database::LoadBalancing do + describe '.base_models' do + it 'returns the models to apply load balancing to' do + models = described_class.base_models + + expect(models).to include(ActiveRecord::Base) + + if Gitlab::Database.has_config?(:ci) + expect(models).to include(Ci::ApplicationRecord) + end + end + + it 'returns the models as a frozen array' do + expect(described_class.base_models).to be_frozen + end + end + end end -- GitLab From cec763598ec9ede78607859cec83841ccadb32b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 22 Nov 2023 11:01:30 +0100 Subject: [PATCH 08/31] Fix Rubocop --- gems/gitlab-database-load_balancing/.rubocop.yml | 1 + gems/gitlab-database-load_balancing/.rubocop_todo.yml | 1 + .../spec/gitlab/database/load_balancing_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gems/gitlab-database-load_balancing/.rubocop.yml b/gems/gitlab-database-load_balancing/.rubocop.yml index 8340cf13f69c26..26b40847d087e9 100644 --- a/gems/gitlab-database-load_balancing/.rubocop.yml +++ b/gems/gitlab-database-load_balancing/.rubocop.yml @@ -9,6 +9,7 @@ Gemfile/MissingFeatureCategory: Database/MultipleDatabases: Exclude: - 'lib/gitlab/database/load_balancing/load_balancer.rb' + - 'spec/gitlab/database/load_balancing_spec.rb' - 'spec/gitlab/database/load_balancing/host_list_spec.rb' - 'spec/gitlab/database/load_balancing/host_spec.rb' - 'spec/gitlab/database/load_balancing/load_balancer_spec.rb' diff --git a/gems/gitlab-database-load_balancing/.rubocop_todo.yml b/gems/gitlab-database-load_balancing/.rubocop_todo.yml index 12a7b201f51cba..94be7317466be8 100644 --- a/gems/gitlab-database-load_balancing/.rubocop_todo.yml +++ b/gems/gitlab-database-load_balancing/.rubocop_todo.yml @@ -38,4 +38,5 @@ Style/Lambda: Style/RedundantSelf: Exclude: + - 'spec/gitlab/database/load_balancing_spec.rb' - 'lib/gitlab/database/load_balancing/service_discovery.rb' diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb index 2c4536223c5a72..fea7e434087908 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb @@ -481,7 +481,7 @@ def current_session end end - context 'custom connection handling' do + context 'with custom connection handling' do where(:queries, :expected_role) do [ # Reload cache. The schema loading queries should be handled by @@ -546,7 +546,7 @@ def current_session end end - context 'a write inside a transaction inside fallback_to_replicas_for_ambiguous_queries block' do + context 'with a write inside a transaction inside fallback_to_replicas_for_ambiguous_queries block' do it 'raises an exception' do expect do ::Gitlab::Database::LoadBalancing::SessionMap -- GitLab From dcfcfe174ea490ad253df61a91a0b02560cb0f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Wed, 22 Nov 2023 12:31:48 +0100 Subject: [PATCH 09/31] Tidy initializer code --- config/initializers/load_balancing.rb | 62 ++++++++----------- .../lib/gitlab/database/load_balancing.rb | 4 ++ spec/initializers/load_balancing_spec.rb | 5 +- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index d8d18466ac9748..28768a3698d7e9 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -1,51 +1,41 @@ # frozen_string_literal: true -Gitlab::Application.configure do |config| - config.middleware.use(Gitlab::Database::LoadBalancing::RackMiddleware) +# Configure Load Balancing +Gitlab::Database::LoadBalancing.configure! do |load_balancer| + load_balancer.enabled = !Gitlab::Runtime.rake? + load_balancer.default_pool_size = Gitlab::Database.default_pool_size + load_balancer.base_models = ::Gitlab::Database.database_base_models_using_load_balancing.values.freeze - # We need re-rerun the setup when code reloads in development - config.reloader.to_prepare do - if Gitlab.dev_or_test_env? - Gitlab::Database::LoadBalancing.base_models.each do |model| - Gitlab::Database::LoadBalancing::Setup.new(model).setup - end - end + Gitlab::Cluster::LifecycleEvents.on_worker_start do + load_balancer.enabled = !Gitlab::Runtime.rake? + load_balancer.default_pool_size = Gitlab::Database.default_pool_size end end -# Configure load balancing -Gitlab::Database::LoadBalancing.enabled = !Gitlab::Runtime.rake? -Gitlab::Database::LoadBalancing.default_pool_size = Gitlab::Database.default_pool_size - -Gitlab::Cluster::LifecycleEvents.on_worker_start do - Gitlab::Database::LoadBalancing.enabled = !Gitlab::Runtime.rake? - Gitlab::Database::LoadBalancing.default_pool_size = Gitlab::Database.default_pool_size -end - -Gitlab::Database::LoadBalancing.base_models = - ::Gitlab::Database.database_base_models_using_load_balancing.values.freeze - -# Configure callbacks +# Configure Load Balancing interface callbacks Gitlab::Database::LoadBalancing::Callbacks.configure! do |callbacks| hosts_gauge = Gitlab::Metrics.gauge(:db_load_balancing_hosts, 'Current number of load balancing hosts') - callbacks.logger_proc = -> do - Gitlab::Database::LoadBalancing::Logger.build - end - callbacks.metrics_host_gauge_proc = ->(labels, value) do - hosts_gauge.set(labels, value) - end - callbacks.track_exception_proc = ->(exception) do - Gitlab::ErrorTracking.track_exception(exception) - end + callbacks.logger_proc = -> { Gitlab::Database::LoadBalancing::Logger.build } + callbacks.metrics_host_gauge_proc = ->(labels, value) { hosts_gauge.set(labels, value) } + callbacks.track_exception_proc = ->(exception) { Gitlab::ErrorTracking.track_exception(exception) } + callbacks.get_wal_for_proc = ->(key) { Gitlab::Redis::DbLoadBalancing.with { |redis| redis.get(key) } } + callbacks.del_wal_for_proc = ->(key) { Gitlab::Redis::DbLoadBalancing.with { |redis| redis.del(key) } } callbacks.set_wal_for_proc = ->(key, value, ex:) do Gitlab::Redis::DbLoadBalancing.with { |redis| redis.set(key, value, ex: ex) } end - callbacks.get_wal_for_proc = ->(key) do - Gitlab::Redis::DbLoadBalancing.with { |redis| redis.get(key) } - end - callbacks.del_wal_for_proc = ->(key) do - Gitlab::Redis::DbLoadBalancing.with { |redis| redis.del(key) } +end + +Gitlab::Application.configure do |config| + config.middleware.use(Gitlab::Database::LoadBalancing::RackMiddleware) + + # We need re-rerun the setup when code reloads in development + config.reloader.to_prepare do + if Gitlab.dev_or_test_env? + Gitlab::Database::LoadBalancing.base_models.each do |model| + Gitlab::Database::LoadBalancing::Setup.new(model).setup + end + end end end diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb index 55f57ba27f89f8..85f65ef099f7d6 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb @@ -32,6 +32,10 @@ module LoadBalancing mattr_accessor :default_pool_size mattr_accessor :enabled, default: true + def self.configure! + yield(self) + end + def self.each_load_balancer return to_enum(__method__) unless block_given? diff --git a/spec/initializers/load_balancing_spec.rb b/spec/initializers/load_balancing_spec.rb index 0f64469615fc61..38f97d95ab1712 100644 --- a/spec/initializers/load_balancing_spec.rb +++ b/spec/initializers/load_balancing_spec.rb @@ -104,10 +104,7 @@ def simulate_puma_worker models = described_class.base_models expect(models).to include(ActiveRecord::Base) - - if Gitlab::Database.has_config?(:ci) - expect(models).to include(Ci::ApplicationRecord) - end + expect(models).to include(Ci::ApplicationRecord) if Gitlab::Database.has_config?(:ci) end it 'returns the models as a frozen array' do -- GitLab From 4d9135b144759412a5b450d40b4865d8df9168fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Thu, 23 Nov 2023 13:38:57 +0100 Subject: [PATCH 10/31] Improve spec_helper --- .../gitlab-database-load_balancing/spec/spec_helper.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index c60e502291be6f..835ce299e823c2 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -32,11 +32,13 @@ end config.before(:all) do - Gitlab::Database::LoadBalancing.default_pool_size = 20 - Gitlab::Database::LoadBalancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] + Gitlab::Database::LoadBalancing.configure! do |load_balancing| + load_balancing.default_pool_size = 20 + load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] - Gitlab::Database::LoadBalancing.base_models.each do |model| - Gitlab::Database::LoadBalancing::Setup.new(model).setup + load_balancing.base_models.each do |model| + Gitlab::Database::LoadBalancing::Setup.new(model).setup + end end end end -- GitLab From ebc9add520f8efa4e7906249f76326fc69dc2195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Thu, 23 Nov 2023 14:32:15 +0000 Subject: [PATCH 11/31] Improve initializer specs --- Gemfile | 2 +- spec/initializers/load_balancing_spec.rb | 69 ++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index d58b8e1b65cdb2..a8ef68911bb14e 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ group :monorepo do end gem 'gitlab-backup-cli', path: 'gems/gitlab-backup-cli', require: 'gitlab/backup/cli', feature_category: :backup_restore -gem 'gitlab-database-load_balancing', path: 'gems/gitlab-database-load_balancing' # rubocop:todo Gemfile/MissingFeatureCategory +gem 'gitlab-database-load_balancing', path: 'gems/gitlab-database-load_balancing', feature_category: :database gem 'gitlab-secret_detection', '< 1.0', feature_category: :secret_detection # Responders respond_to and respond_with diff --git a/spec/initializers/load_balancing_spec.rb b/spec/initializers/load_balancing_spec.rb index 38f97d95ab1712..8cc4bfdc099070 100644 --- a/spec/initializers/load_balancing_spec.rb +++ b/spec/initializers/load_balancing_spec.rb @@ -112,4 +112,73 @@ def simulate_puma_worker end end end + + describe Gitlab::Database::LoadBalancing::Callbacks do + describe '.metrics_host_gauge' do + it 'sets prometheus metric' do + expect(described_class).to receive(:metrics_host_gauge) + .with({}, 1).and_call_original + + # Metric will be set once configured host list: + # - 1 host since we only have primary + # - this test will fail if running CI against replicas + model = Gitlab::Database::LoadBalancing.base_models.first + Gitlab::Database::LoadBalancing::Setup.new(model).setup + + metric = ::Prometheus::Client.registry.get(:db_load_balancing_hosts) + expect(metric).not_to be_nil + expect(metric.values[{}].get).to eq(1) + end + end + + context 'when sticking connection', :database_replica, :redis do + let(:key) { 'database-load-balancing/write-location/main/user/100' } + let(:wal) { '0/D525E3A8' } + + it 'does set latest WAL and unstick once caught-up' do + allow(ApplicationRecord.load_balancer).to receive(:primary_write_location).and_return(wal) + + expect(described_class).to receive(:set_wal_for) + .with(key, wal, ex: 30) + .and_call_original + + expect { ApplicationRecord.sticking.stick(:user, 100) } + .to change { described_class.get_wal_for(key) }.from(nil).to(wal) + + expect(described_class).to receive(:del_wal_for) + .with(key).and_call_original + + expect { ApplicationRecord.sticking.find_caught_up_replica(:user, 100) } + .to change { described_class.get_wal_for(key) }.from(wal).to(nil) + end + + describe '.set_wal_for' do + it 'does get latest set value' do + expect { described_class.set_wal_for(key, wal, ex: 30) } + .to change { described_class.get_wal_for(key) }.from(nil).to(wal) + end + end + + describe '.del_wal_for' do + it 'does delete set value' do + described_class.set_wal_for(key, wal, ex: 30) + + expect { described_class.del_wal_for(key) } + .to change { described_class.get_wal_for(key) }.from(wal).to(nil) + end + end + end + + describe '.track_exception' do + it 'forwards exception to ErrorTracking' do + expect(Gitlab::ErrorTracking).to receive(:track_exception) + .with(Gitlab::Utils::ConcurrentRubyThreadIsUsedError) + + Gitlab::Utils.restrict_within_concurrent_ruby do + expect { ApplicationRecord.connection.execute("SELECT 1") } + .to raise_error(Gitlab::Utils::ConcurrentRubyThreadIsUsedError) + end + end + end + end end -- GitLab From 471abb252769b2b5a6c8a41617165f6bc6e3dc41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Tue, 28 Nov 2023 11:51:55 +0100 Subject: [PATCH 12/31] Fix rspec --- spec/initializers/load_balancing_spec.rb | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/spec/initializers/load_balancing_spec.rb b/spec/initializers/load_balancing_spec.rb index 8cc4bfdc099070..0b483d059cb23d 100644 --- a/spec/initializers/load_balancing_spec.rb +++ b/spec/initializers/load_balancing_spec.rb @@ -2,18 +2,16 @@ require 'spec_helper' -RSpec.describe 'load_balancing', :delete, :reestablished_active_record_base, feature_category: :cell do - subject(:initialize_load_balancer) do - load Rails.root.join('config/initializers/load_balancing.rb') - end - - before do - # Stub out middleware call, as not idempotent - allow(Gitlab::Application.instance.middleware).to receive(:use) - end +RSpec.describe 'load_balancing', feature_category: :cell do + context 'with replica hosts configured', :delete, :reestablished_active_record_base do + subject(:initialize_load_balancer) do + load Rails.root.join('config/initializers/load_balancing.rb') + end - context 'with replica hosts configured' do before do + # Stub out middleware call, as not idempotent + allow(Gitlab::Application.instance.middleware).to receive(:use) + # Setup host-based load balancing # Patch in our load balancer config, simply pointing at the test database twice allow(Gitlab::Database::LoadBalancing::Configuration).to receive(:for_model) do |base_model| @@ -115,7 +113,7 @@ def simulate_puma_worker describe Gitlab::Database::LoadBalancing::Callbacks do describe '.metrics_host_gauge' do - it 'sets prometheus metric' do + it 'sets prometheus metric', :reestablished_active_record_base do expect(described_class).to receive(:metrics_host_gauge) .with({}, 1).and_call_original @@ -131,7 +129,7 @@ def simulate_puma_worker end end - context 'when sticking connection', :database_replica, :redis do + context 'when sticking connection', :database_replica, :redis, :request_store do let(:key) { 'database-load-balancing/write-location/main/user/100' } let(:wal) { '0/D525E3A8' } @@ -148,6 +146,9 @@ def simulate_puma_worker expect(described_class).to receive(:del_wal_for) .with(key).and_call_original + expect(ApplicationRecord.load_balancer).to receive(:select_up_to_date_host) + .with(wal).and_return(Gitlab::Database::LoadBalancing::LoadBalancer::ALL_CAUGHT_UP) + expect { ApplicationRecord.sticking.find_caught_up_replica(:user, 100) } .to change { described_class.get_wal_for(key) }.from(wal).to(nil) end -- GitLab From 31fb41a9fc4724c62a926eb7893098b14e1d37fa Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Mon, 19 May 2025 14:43:16 -0500 Subject: [PATCH 13/31] Move session_map to gem, fix feature flag checks --- config/initializers/load_balancing.rb | 4 ++++ .../lib/gitlab/database/load_balancing/callbacks.rb | 5 +++++ .../lib/gitlab/database/load_balancing/host.rb | 6 +++--- .../lib}/gitlab/database/load_balancing/session_map.rb | 0 .../spec/gitlab/database/load_balancing/host_spec.rb | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) rename {lib => gems/gitlab-database-load_balancing/lib}/gitlab/database/load_balancing/session_map.rb (100%) diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 28768a3698d7e9..6fcfdd57074465 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -24,6 +24,10 @@ callbacks.set_wal_for_proc = ->(key, value, ex:) do Gitlab::Redis::DbLoadBalancing.with { |redis| redis.set(key, value, ex: ex) } end + + callbacks.check_feature_flag = ->(key, thing, type: nil) do + Feature.enabled?(key, thing, type: type) + end end Gitlab::Application.configure do |config| diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index 086819e016ba93..e7b84aa46d5416 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -7,6 +7,7 @@ module Callbacks mattr_accessor :logger_proc mattr_accessor :metrics_host_gauge_proc, :track_exception_proc mattr_accessor :set_wal_for_proc, :get_wal_for_proc, :del_wal_for_proc + mattr_accessor :check_feature_flag NULL_LOGGER = Logger.new(File::NULL) @@ -37,6 +38,10 @@ def self.metrics_host_gauge(labels, value) def self.track_exception(ex) track_exception_proc&.call(ex) end + + def self.feature_enabled?(key, thing, type: nil) + check_feature_flag&.call(key, thing, type: type) + end end end end diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb index b95b1e30f7b929..04b4bfd7e0359a 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb @@ -328,15 +328,15 @@ def latest_lsn_query end def ignore_replication_lag_time? - Feature.enabled?(:load_balancer_ignore_replication_lag_time, type: :ops) + Gitlab::Database::LoadBalancing::Callbacks.feature_enabled?(:load_balancer_ignore_replication_lag_time, type: :ops) end def double_replication_lag_time? - Feature.enabled?(:load_balancer_double_replication_lag_time, type: :ops) + Gitlab::Database::LoadBalancing::Callbacks.feature_enabled?(:load_balancer_double_replication_lag_time, type: :ops) end def low_timeout_for_host_queries? - Feature.enabled?(:load_balancer_low_statement_timeout, Feature.current_pod) + Gitlab::Database::LoadBalancing::Callbacks.feature_enabled?(:load_balancer_low_statement_timeout, :current_pod) end end end diff --git a/lib/gitlab/database/load_balancing/session_map.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb similarity index 100% rename from lib/gitlab/database/load_balancing/session_map.rb rename to gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index 9eff5d1f2d3d48..cb6eb80e44a01f 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -426,7 +426,7 @@ def wrapped_exception(wrapper, original) context 'with the flag set' do before do - stub_feature_flags(load_balancer_low_statement_timeout: Feature.current_pod) + stub_feature_flags(load_balancer_low_statement_timeout: :current_pod) end it 'returns quickly if the underlying query takes a long time' do -- GitLab From 1bf72a09ee7fd8ad9c75750cd583f1622c731b8b Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Tue, 20 May 2025 13:21:16 -0500 Subject: [PATCH 14/31] Configure session map in gem --- config/initializers/0_migration_paths_additional.rb | 8 ++++++++ config/initializers/load_balancing.rb | 1 + .../lib/gitlab/database/load_balancing.rb | 1 + .../lib/gitlab/database/load_balancing/session_map.rb | 2 +- .../spec/gitlab/database/load_balancing/host_spec.rb | 9 ++++++--- gems/gitlab-database-load_balancing/spec/spec_helper.rb | 3 ++- .../spec/support/database_replica.rb | 4 ++-- .../spec/support/feature_flags.rb | 2 ++ 8 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 gems/gitlab-database-load_balancing/spec/support/feature_flags.rb diff --git a/config/initializers/0_migration_paths_additional.rb b/config/initializers/0_migration_paths_additional.rb index bf0c36e9bb6b8d..64228fe4c996ee 100644 --- a/config/initializers/0_migration_paths_additional.rb +++ b/config/initializers/0_migration_paths_additional.rb @@ -6,4 +6,12 @@ # Post deployment migrations are included by default. This file must be loaded # before other initializers as Rails may otherwise memoize a list of migrations # excluding the post deployment migrations. + +# During the split of load balancing to a gem, we've already loaded Gitlab::Database::LoadBalancing before this line runs +# As a result, we don't trigger an auto-load of Gitlab::Database from lib/gitlab/database.rb . +# Force load that file to fix this temporarily +# TODO: fix this before merge +# TODO: understand why this isn't a problem for calls like `Gitlab.com?` too +require Rails.root.join('lib/gitlab/database.rb') + Gitlab::Database.add_post_migrate_path_to_rails diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 6fcfdd57074465..552ce4780c3637 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -5,6 +5,7 @@ load_balancer.enabled = !Gitlab::Runtime.rake? load_balancer.default_pool_size = Gitlab::Database.default_pool_size load_balancer.base_models = ::Gitlab::Database.database_base_models_using_load_balancing.values.freeze + load_balancer.all_database_names = ::Gitlab::Database.all_database_names.freeze Gitlab::Cluster::LifecycleEvents.on_worker_start do load_balancer.enabled = !Gitlab::Runtime.rake? diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb index 85f65ef099f7d6..21985ad7c16e7c 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb @@ -29,6 +29,7 @@ module LoadBalancing ].freeze mattr_accessor :base_models + mattr_accessor :all_database_names mattr_accessor :default_pool_size mattr_accessor :enabled, default: true diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb index 3eb52d2b378e60..fe9b6eb60de4f2 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb @@ -40,7 +40,7 @@ def self.cached_instance attr_reader :session_map def initialize - @session_map = Gitlab::Database.all_database_names.to_h do |k| + @session_map = Gitlab::Database::LoadBalancing.all_database_names.to_h do |k| [k.to_sym, Gitlab::Database::LoadBalancing::Session.new] end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index cb6eb80e44a01f..68ecd2a38ebe01 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -316,7 +316,8 @@ def wrapped_exception(wrapper, original) end end - describe '#replication_lag_below_threshold' do + # TODO: Figure out flag stubbing and re-enable + xdescribe '#replication_lag_below_threshold' do let(:load_balancer_double_replication_lag_time) { false } let(:load_balancer_ignore_replication_lag_time) { false } @@ -424,7 +425,8 @@ def wrapped_exception(wrapper, original) expect(host.replication_lag_time).to be_nil end - context 'with the flag set' do + # TODO: Figure out flag stubbing and fix + xcontext 'with the flag set' do before do stub_feature_flags(load_balancer_low_statement_timeout: :current_pod) end @@ -469,7 +471,8 @@ def wrapped_exception(wrapper, original) end end - context 'with the flag not set' do + # TODO: Figure out flag stubbing and fix + xcontext 'with the flag not set' do before do stub_feature_flags(load_balancer_low_statement_timeout: false) end diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index 835ce299e823c2..d88db428b10017 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -34,7 +34,8 @@ config.before(:all) do Gitlab::Database::LoadBalancing.configure! do |load_balancing| load_balancing.default_pool_size = 20 - load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] + load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] # TODO support sec? Or abstract away from it? + load_balancing.all_database_names = %w[main ci] load_balancing.base_models.each do |model| Gitlab::Database::LoadBalancing::Setup.new(model).setup diff --git a/gems/gitlab-database-load_balancing/spec/support/database_replica.rb b/gems/gitlab-database-load_balancing/spec/support/database_replica.rb index b37540105a8e10..7df712e2fdac7c 100644 --- a/gems/gitlab-database-load_balancing/spec/support/database_replica.rb +++ b/gems/gitlab-database-load_balancing/spec/support/database_replica.rb @@ -15,11 +15,11 @@ model.connection = Gitlab::Database::LoadBalancing::ConnectionProxy.new(model.load_balancer) end - Gitlab::Database::LoadBalancing::Session.clear_session + Gitlab::Database::LoadBalancing::SessionMap.clear_session example.run - Gitlab::Database::LoadBalancing::Session.clear_session + Gitlab::Database::LoadBalancing::SessionMap.clear_session old_proxies.each do |model, proxy| model.load_balancer, model.connection, model.sticking = proxy diff --git a/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb b/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb new file mode 100644 index 00000000000000..0d81020d8d8063 --- /dev/null +++ b/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb @@ -0,0 +1,2 @@ + +def stub_feature_flags() -- GitLab From 059a4206fddf9df2355676072b152888015a5523 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 21 May 2025 13:32:03 -0500 Subject: [PATCH 15/31] wip fixing tests --- .../lib/gitlab/database/load_balancing/host.rb | 4 ++++ .../database/load_balancing/service_discovery.rb | 4 ++++ .../load_balancing/service_discovery_spec.rb | 13 +++++++++---- .../spec/support/feature_flags.rb | 2 -- 4 files changed, 17 insertions(+), 6 deletions(-) delete mode 100644 gems/gitlab-database-load_balancing/spec/support/feature_flags.rb diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb index 04b4bfd7e0359a..7a71f292cedf38 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb @@ -311,6 +311,10 @@ def query_and_release_fast_timeout(sql) end end + def inspect + "<#{self.class.name} host:#{@host} port:#{@port}>" + end + private def can_track_logical_lsn? diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb index 08945b91dd5d02..6f85ae52748637 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery.rb @@ -221,6 +221,10 @@ def log_refresh_thread_interruption self.refresh_thread_interruption_logged = true end + def inspect + "<#{self.class.name} nameserver:#{@nameserver}, port:#{@port}>" + end + private def record_type_for(type) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb index bf6139950f247a..cfa513c1c5c2b8 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb @@ -197,6 +197,11 @@ allow(service) .to receive(:load_balancer) .and_return(load_balancer) + + # TODO: real feature flag stubbing + allow(Gitlab::Database::LoadBalancing::Callbacks).to receive(:feature_enabled?) + .with(:load_balancer_replace_hosts, :current_pod) + .and_return(true) end let(:address_foo) { described_class::Address.new('foo') } @@ -543,8 +548,8 @@ end gentle_disconnected_hosts = service.load_balancer.host_list.hosts.map { |h| "#{h.host}:#{h.port}" } - allow(::Gitlab::Database::LoadBalancing::Logger).to receive(:info).and_call_original - expect(::Gitlab::Database::LoadBalancing::Logger).to receive(:info) + allow(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info).and_call_original + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info) .with(hash_including( event: :host_list_disconnection, gentle_disconnected_hosts: gentle_disconnected_hosts, @@ -565,8 +570,8 @@ expect(connection).to receive(:steal!).and_call_original allow(service).to receive(:addresses_from_dns).and_return([Gitlab::Database::LoadBalancing::Resolver::FAR_FUTURE_TTL, []]) - allow(::Gitlab::Database::LoadBalancing::Logger).to receive(:info).and_call_original - expect(::Gitlab::Database::LoadBalancing::Logger).to receive(:info) + allow(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info).and_call_original + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info) .with(hash_including( event: :host_list_disconnection, force_disconnected_hosts: ["#{host.host}:#{host.port}"] diff --git a/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb b/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb deleted file mode 100644 index 0d81020d8d8063..00000000000000 --- a/gems/gitlab-database-load_balancing/spec/support/feature_flags.rb +++ /dev/null @@ -1,2 +0,0 @@ - -def stub_feature_flags() -- GitLab From b3d601eb9574f11441a9981b83d6255eccb97889 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Thu, 22 May 2025 11:26:45 -0500 Subject: [PATCH 16/31] Fix rubocop errors --- .../lib/gitlab/database/load_balancing.rb | 2 +- .../spec/gitlab/database/load_balancing/host_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb index 21985ad7c16e7c..328744f3fcaf9e 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing.rb @@ -90,7 +90,7 @@ def self.db_config_for_connection(connection) # During application init we might receive `NullPool` return unless connection.respond_to?(:pool) && - connection.pool.respond_to?(:db_config) + connection.pool.respond_to?(:db_config) db_config = connection.pool.db_config db_config unless empty_config?(db_config) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index 68ecd2a38ebe01..495940cc15f252 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -451,7 +451,7 @@ def wrapped_exception(wrapper, original) it 'does not use a low statement timeout if a transaction is already open' do allow(host.connection).to receive(:select_all).and_call_original expect(host.connection).to receive(:select_all).with(described_class::REPLICATION_LAG_QUERY) do - host.connection.select_all(<<~SQL) + host.connection.select_all(<<~SQL.squish) select EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::float as lag, pg_sleep(1) @@ -480,7 +480,7 @@ def wrapped_exception(wrapper, original) it 'waits for the underlying query when it takes a long time' do allow(host.connection).to receive(:select_all).and_call_original expect(host.connection).to receive(:select_all).with(described_class::REPLICATION_LAG_QUERY).once do - host.connection.select_all(<<~SQL) + host.connection.select_all(<<~SQL.squish) SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::float as lag, pg_sleep(1) as sleep -- GitLab From b785ccf4664490479b5e8306d9956652950678fc Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Thu, 22 May 2025 11:45:23 -0500 Subject: [PATCH 17/31] Fix autoloading patch --- Gemfile | 6 +++++- config/initializers/0_migration_paths_additional.rb | 8 -------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index a8ef68911bb14e..d3a05e3eeb1053 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,11 @@ group :monorepo do end gem 'gitlab-backup-cli', path: 'gems/gitlab-backup-cli', require: 'gitlab/backup/cli', feature_category: :backup_restore -gem 'gitlab-database-load_balancing', path: 'gems/gitlab-database-load_balancing', feature_category: :database +# load_balancing is manually required at the top of lib/gitlab/database.rb +# Otherwise the module Gitlab::Database::LoadBalancing would make an empty Gitlab::Database module and +# confuse the autoloader into skipping loading lib/gitlab/database.rb +gem 'gitlab-database-load_balancing', path: 'gems/gitlab-database-load_balancing', require: false, + feature_category: :database gem 'gitlab-secret_detection', '< 1.0', feature_category: :secret_detection # Responders respond_to and respond_with diff --git a/config/initializers/0_migration_paths_additional.rb b/config/initializers/0_migration_paths_additional.rb index 64228fe4c996ee..bf0c36e9bb6b8d 100644 --- a/config/initializers/0_migration_paths_additional.rb +++ b/config/initializers/0_migration_paths_additional.rb @@ -6,12 +6,4 @@ # Post deployment migrations are included by default. This file must be loaded # before other initializers as Rails may otherwise memoize a list of migrations # excluding the post deployment migrations. - -# During the split of load balancing to a gem, we've already loaded Gitlab::Database::LoadBalancing before this line runs -# As a result, we don't trigger an auto-load of Gitlab::Database from lib/gitlab/database.rb . -# Force load that file to fix this temporarily -# TODO: fix this before merge -# TODO: understand why this isn't a problem for calls like `Gitlab.com?` too -require Rails.root.join('lib/gitlab/database.rb') - Gitlab::Database.add_post_migrate_path_to_rails -- GitLab From 92a51eba222979606940e60defeab839fdcea41a Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Thu, 22 May 2025 14:25:28 -0500 Subject: [PATCH 18/31] Fix rubocop warnings --- config/initializers/load_balancing.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/initializers/load_balancing.rb b/config/initializers/load_balancing.rb index 552ce4780c3637..2b397af691170f 100644 --- a/config/initializers/load_balancing.rb +++ b/config/initializers/load_balancing.rb @@ -27,7 +27,9 @@ end callbacks.check_feature_flag = ->(key, thing, type: nil) do + # rubocop:disable Gitlab/FeatureFlagKeyDynamic -- passing through literal feature flag calls from gem Feature.enabled?(key, thing, type: type) + # rubocop:enable Gitlab/FeatureFlagKeyDynamic end end -- GitLab From 0a9964acb211087cdffdcd96689f2bed7021010f Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Thu, 22 May 2025 14:50:12 -0500 Subject: [PATCH 19/31] Handle feature flags in load balancer gem specs --- .../gitlab/database/load_balancing/host.rb | 6 ++-- .../database/load_balancing/host_spec.rb | 28 ++++++++++--------- .../spec/spec_helper.rb | 2 ++ .../stub_load_balancer_feature_flags.rb | 7 +++++ 4 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb index 7a71f292cedf38..a7f589f6cde513 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/host.rb @@ -182,7 +182,7 @@ def replication_lag_below_threshold? return true if @lag_time <= load_balancer.configuration.max_replication_lag_time if ignore_replication_lag_time? - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :replication_lag_ignored, lag_time: @lag_time, message: 'Replication lag is treated as low because of load_balancer_ignore_replication_lag_time feature flag' @@ -192,7 +192,7 @@ def replication_lag_below_threshold? end if double_replication_lag_time? && @lag_time <= (load_balancer.configuration.max_replication_lag_time * 2) - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :replication_lag_below_double, lag_time: @lag_time, message: 'Replication lag is treated as low because of load_balancer_double_replication_lag_time feature flag' @@ -292,7 +292,7 @@ def query_and_release_fast_timeout(sql) # However, we don't ever run transactions on replicas, and we only do these health checks on replicas. # Double-check that we're not in a transaction, but this path should never happen. if connection.transaction_open? - Gitlab::Database::LoadBalancing::Logger.warn( + Gitlab::Database::LoadBalancing::Callbacks.logger.warn( event: :health_check_in_transaction, message: "Attempt to run a health check query inside of a transaction" ) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index 495940cc15f252..f130fa2aadd4fa 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -317,13 +317,13 @@ def wrapped_exception(wrapper, original) end # TODO: Figure out flag stubbing and re-enable - xdescribe '#replication_lag_below_threshold' do + describe '#replication_lag_below_threshold' do let(:load_balancer_double_replication_lag_time) { false } let(:load_balancer_ignore_replication_lag_time) { false } before do - stub_feature_flags(load_balancer_double_replication_lag_time: load_balancer_double_replication_lag_time) - stub_feature_flags(load_balancer_ignore_replication_lag_time: load_balancer_ignore_replication_lag_time) + stub_load_balancer_feature_flags(load_balancer_double_replication_lag_time: load_balancer_double_replication_lag_time) + stub_load_balancer_feature_flags(load_balancer_ignore_replication_lag_time: load_balancer_ignore_replication_lag_time) end it 'returns true when the lag time is below the threshold' do @@ -426,13 +426,12 @@ def wrapped_exception(wrapper, original) end # TODO: Figure out flag stubbing and fix - xcontext 'with the flag set' do + context 'with the flag set' do before do - stub_feature_flags(load_balancer_low_statement_timeout: :current_pod) + stub_load_balancer_feature_flags(load_balancer_low_statement_timeout: true) end it 'returns quickly if the underlying query takes a long time' do - allow(host.connection).to receive(:transaction_open?).and_return(false) allow(host.connection).to receive(:select_all).and_call_original expect(host.connection).to receive(:select_all).with(described_class::REPLICATION_LAG_QUERY) do host.connection.select_all('select pg_sleep(5)') @@ -452,19 +451,22 @@ def wrapped_exception(wrapper, original) allow(host.connection).to receive(:select_all).and_call_original expect(host.connection).to receive(:select_all).with(described_class::REPLICATION_LAG_QUERY) do host.connection.select_all(<<~SQL.squish) - select - EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::float as lag, - pg_sleep(1) + select + EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::float as lag, + pg_sleep(1) SQL end - expect(Gitlab::Database::LoadBalancing::Logger) + expect(Gitlab::Database::LoadBalancing::Callbacks.logger) .to receive(:warn).with(hash_including(event: :health_check_in_transaction)) duration = Benchmark.realtime do # without a low statement timeout the query succeeds and gives the real lag time # 0 lag because this isn't a replica during testing - expect(host.replication_lag_time).to eq(0.0) + # Must open an explicit transaction - gem testing isn't wrapping tests in transactions by default + host.connection.transaction do + expect(host.replication_lag_time).to eq(0.0) + end end # We waited at least 1 second for the pg_sleep(1) expect(duration).to be > (1) @@ -472,9 +474,9 @@ def wrapped_exception(wrapper, original) end # TODO: Figure out flag stubbing and fix - xcontext 'with the flag not set' do + context 'with the flag not set' do before do - stub_feature_flags(load_balancer_low_statement_timeout: false) + stub_load_balancer_feature_flags(load_balancer_low_statement_timeout: false) end it 'waits for the underlying query when it takes a long time' do diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index d88db428b10017..24c6420ccfe6ee 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -12,10 +12,12 @@ require_relative 'support/database_replica' require_relative 'support/application_record' +require_relative 'support/stub_load_balancer_feature_flags' RSpec.configure do |config| include StubRails include NextInstanceOf + include StubLoadBalancerFeatureFlags # Enable flags like --only-failures and --next-failure config.example_status_persistence_file_path = ".rspec_status" diff --git a/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb b/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb new file mode 100644 index 00000000000000..65af058f603895 --- /dev/null +++ b/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb @@ -0,0 +1,7 @@ +module StubLoadBalancerFeatureFlags + def stub_load_balancer_feature_flags(flag_mappings) + flag_mappings.each do |flag, value| + allow(Gitlab::Database::LoadBalancing::Callbacks).to receive(:feature_enabled?).with(flag, anything).and_return(value) + end + end +end -- GitLab From d4f70debe335bf7dec2cae6a59f8c580d9ee2cf1 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Tue, 27 May 2025 14:14:27 -0500 Subject: [PATCH 20/31] Fix rubocop errors --- .../spec/support/stub_load_balancer_feature_flags.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb b/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb index 65af058f603895..8d2ff99626190b 100644 --- a/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb +++ b/gems/gitlab-database-load_balancing/spec/support/stub_load_balancer_feature_flags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module StubLoadBalancerFeatureFlags def stub_load_balancer_feature_flags(flag_mappings) flag_mappings.each do |flag, value| -- GitLab From ef3e8b93f45871f3cb819e1e7c44ec0346bcd78c Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Fri, 30 May 2025 12:31:01 -0500 Subject: [PATCH 21/31] Move SessionMap to load balancer gem This moves the session map class and its specs to the load balancer gem Cuts out references to Gitlab::Runtime from the session map, and from its specs. These references were only used to enrich error messages, and removing them makes the extraction much simpler. --- .../database/load_balancing/session_map.rb | 8 ++-- .../load_balancing/session_map_spec.rb | 48 ++++++------------- .../spec/spec_helper.rb | 4 +- .../spec/support/application_record.rb | 6 +++ 4 files changed, 26 insertions(+), 40 deletions(-) rename {spec/lib => gems/gitlab-database-load_balancing/spec}/gitlab/database/load_balancing/session_map_spec.rb (83%) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb index fe9b6eb60de4f2..49cbac0b22335a 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/session_map.rb @@ -55,7 +55,7 @@ def lookup(load_balancer) def validate_db_name(db) if db == :primary - # Allow :primary in general but report the exeception. We should expect primary for: + # Allow :primary in general but report the exception. We should expect primary for: # # 1. rake task db migrations as ActiveRecord::Tasks::PostgresqlDatabaseTasks calls # .establish_connection using a hash which resets the name from :main/:ci to :primary. @@ -64,8 +64,8 @@ def validate_db_name(db) # # 2. In the case of derailed test in memory-on-boot job, the runtime is unknown. # 3. `scripts/regenerate-schema` which runs in RAILS_ENV=test - Gitlab::ErrorTracking.track_exception( - InvalidLoadBalancerNameError.new("Using #{db} load balancer in #{Gitlab::Runtime.safe_identify}.") + Gitlab::Database::LoadBalancing::Callbacks.track_exception( + InvalidLoadBalancerNameError.new("Using #{db} load balancer") ) return @@ -74,7 +74,7 @@ def validate_db_name(db) return if session_map[db] # All other load balancer names are invalid and should raise an error - raise InvalidLoadBalancerNameError, "Invalid load balancer name #{db} in #{Gitlab::Runtime.safe_identify}." + raise InvalidLoadBalancerNameError, "Invalid load balancer name #{db}." end end diff --git a/spec/lib/gitlab/database/load_balancing/session_map_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb similarity index 83% rename from spec/lib/gitlab/database/load_balancing/session_map_spec.rb rename to gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb index 929fc056424807..9de89d4d7b9c39 100644 --- a/spec/lib/gitlab/database/load_balancing/session_map_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb @@ -40,7 +40,6 @@ let(:pri_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } before do - allow(Gitlab::Runtime).to receive(:rake?).and_return(true) sm = described_class.new sm.session_map[:primary] = pri_session RequestStore[described_class::CACHE_KEY] = sm @@ -61,43 +60,24 @@ subject(:current) { described_class.current(lb) } - Gitlab::Runtime::AVAILABLE_RUNTIMES.each do |runtime| - context "when using #{runtime} runtime" do - before do - allow(Gitlab::Runtime).to receive(runtime).and_return(true) - allow(Gitlab::Runtime).to receive(:safe_identify).and_return(runtime) - end - - context 'when db is invalid' do - let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :invalid) } - - it 'raises error' do - expect do - current - end.to raise_error(instance_of(Gitlab::Database::LoadBalancing::SessionMap::InvalidLoadBalancerNameError)) - end - end + context 'when db is invalid' do + let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :invalid) } - context 'when db is primary' do - let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } - - it 'reports error without raising' do - expect(Gitlab::ErrorTracking).to receive(:track_exception) - .with(an_instance_of(Gitlab::Database::LoadBalancing::SessionMap::InvalidLoadBalancerNameError)) - expect(current).to be_instance_of(Gitlab::Database::LoadBalancing::Session) - end - end + it 'raises error' do + expect do + current + end.to raise_error(instance_of(Gitlab::Database::LoadBalancing::SessionMap::InvalidLoadBalancerNameError)) end end - it 'handles unknown runtimes' do - allow(Gitlab::Runtime).to receive(:rake?).and_return(false) - allow(Gitlab::Runtime).to receive(:safe_identify).and_return(nil) + context 'when db is primary' do + let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } - expect(described_class.current(pri_lb)).to be_instance_of(Gitlab::Database::LoadBalancing::Session) - expect do - described_class.current(invalid_lb) - end.to raise_error(instance_of(Gitlab::Database::LoadBalancing::SessionMap::InvalidLoadBalancerNameError)) + it 'reports error without raising' do + expect(Gitlab::Database::LoadBalancing::Callbacks).to receive(:track_exception) + .with(an_instance_of(Gitlab::Database::LoadBalancing::SessionMap::InvalidLoadBalancerNameError)) + expect(current).to be_instance_of(Gitlab::Database::LoadBalancing::Session) + end end end end @@ -115,7 +95,7 @@ end context 'when wrapping queries with load balancing sessions' do - let(:dbs) { Gitlab::Database.database_base_models.values } + let(:dbs) { Gitlab::Database::LoadBalancing.base_models } let(:names) { dbs.map { |m| m.load_balancer.name }.uniq } let(:scoped_session) { Gitlab::Database::LoadBalancing::ScopedSessions.new(dbs, {}) } diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index 24c6420ccfe6ee..5a572537bd4c8c 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -36,8 +36,8 @@ config.before(:all) do Gitlab::Database::LoadBalancing.configure! do |load_balancing| load_balancing.default_pool_size = 20 - load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord] # TODO support sec? Or abstract away from it? - load_balancing.all_database_names = %w[main ci] + load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord, Sec::ApplicationRecord] # TODO support sec? Or abstract away from it? + load_balancing.all_database_names = %w[main ci sec] load_balancing.base_models.each do |model| Gitlab::Database::LoadBalancing::Setup.new(model).setup diff --git a/gems/gitlab-database-load_balancing/spec/support/application_record.rb b/gems/gitlab-database-load_balancing/spec/support/application_record.rb index acea00b5072cc1..07f9179ae62e31 100644 --- a/gems/gitlab-database-load_balancing/spec/support/application_record.rb +++ b/gems/gitlab-database-load_balancing/spec/support/application_record.rb @@ -9,3 +9,9 @@ class ApplicationRecord < ApplicationRecord self.abstract_class = true end end + +module Sec + class ApplicationRecord < ApplicationRecord + self.abstract_class = true + end +end -- GitLab From fa98e5d349664af7942013b5959d12a30c8ece4f Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 4 Jun 2025 11:05:47 -0500 Subject: [PATCH 22/31] Fix rubocop --- gems/gitlab-database-load_balancing/.rubocop.yml | 4 +++- gems/gitlab-database-load_balancing/spec/spec_helper.rb | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/gems/gitlab-database-load_balancing/.rubocop.yml b/gems/gitlab-database-load_balancing/.rubocop.yml index 26b40847d087e9..03e87fb1632f11 100644 --- a/gems/gitlab-database-load_balancing/.rubocop.yml +++ b/gems/gitlab-database-load_balancing/.rubocop.yml @@ -35,8 +35,10 @@ RSpec/ImplicitSubject: Exclude: - 'spec/gitlab/database/load_balancing/configuration_spec.rb' +# Configuration parameters: AllowSubject. RSpec/MultipleMemoizedHelpers: - Max: 9 + Max: 25 + AllowSubject: true RSpec/VerifiedDoubles: Exclude: diff --git a/gems/gitlab-database-load_balancing/spec/spec_helper.rb b/gems/gitlab-database-load_balancing/spec/spec_helper.rb index 5a572537bd4c8c..80e3f60b24d33a 100644 --- a/gems/gitlab-database-load_balancing/spec/spec_helper.rb +++ b/gems/gitlab-database-load_balancing/spec/spec_helper.rb @@ -36,7 +36,8 @@ config.before(:all) do Gitlab::Database::LoadBalancing.configure! do |load_balancing| load_balancing.default_pool_size = 20 - load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord, Sec::ApplicationRecord] # TODO support sec? Or abstract away from it? + # TODO support sec? Or abstract away from it + load_balancing.base_models = [ActiveRecord::Base, Ci::ApplicationRecord, Sec::ApplicationRecord] load_balancing.all_database_names = %w[main ci sec] load_balancing.base_models.each do |model| -- GitLab From 49e5ba2d0fe0357498ab178ba2c5d0db63966eab Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Tue, 17 Jun 2025 13:51:20 -0500 Subject: [PATCH 23/31] Exclude load balancer feature flags from check These feature flags are used in the load balancer gem, so the check script cannot find their usage. Treat them the same as gitaly flags - assume that they are used. --- scripts/feature_flags/used-feature-flags | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/feature_flags/used-feature-flags b/scripts/feature_flags/used-feature-flags index 0bb47a5f622e79..7285d721f4c2e3 100755 --- a/scripts/feature_flags/used-feature-flags +++ b/scripts/feature_flags/used-feature-flags @@ -71,6 +71,11 @@ Dir.glob(flag_definition_paths).each do |flag_definition_path| next end + if feature_flag_name.start_with?('load_balancer_') + puts "Skipping the #{feature_flag_name} feature flag since it starts with 'load_balancer_'." + next + end + all_flags[feature_flag_name] = File.exist?(File.join('tmp', 'feature_flags', "#{feature_flag_name}.used")) end -- GitLab From 6ac79ab047d82afb4a3973029034d992c2337ff1 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Tue, 17 Jun 2025 14:11:37 -0500 Subject: [PATCH 24/31] Remove fixed todo for load balancer flag stubbing --- .../spec/gitlab/database/load_balancing/host_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index f130fa2aadd4fa..184b8def64b725 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -316,7 +316,6 @@ def wrapped_exception(wrapper, original) end end - # TODO: Figure out flag stubbing and re-enable describe '#replication_lag_below_threshold' do let(:load_balancer_double_replication_lag_time) { false } let(:load_balancer_ignore_replication_lag_time) { false } -- GitLab From 840751972e6a24d0a61349b073a480e46d304e7d Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 18 Jun 2025 11:27:21 -0500 Subject: [PATCH 25/31] Allow feature flag checks without an actor --- .../lib/gitlab/database/load_balancing/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index e7b84aa46d5416..c3ba346201028d 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -39,7 +39,7 @@ def self.track_exception(ex) track_exception_proc&.call(ex) end - def self.feature_enabled?(key, thing, type: nil) + def self.feature_enabled?(key, thing = nil, type: nil) check_feature_flag&.call(key, thing, type: type) end end -- GitLab From be85fa55f3d7e7214ff8f8c1b9dca307906f9cd5 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 18 Jun 2025 11:26:46 -0500 Subject: [PATCH 26/31] Only allow load_balancer feature flags in gem --- .../database/load_balancing/callbacks.rb | 1 + .../database/load_balancing/callbacks_spec.rb | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index c3ba346201028d..2585cfab4a02e7 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -40,6 +40,7 @@ def self.track_exception(ex) end def self.feature_enabled?(key, thing = nil, type: nil) + raise "Unsupported feature flag #{key}" unless key.to_s.start_with?("load_balancer_") check_feature_flag&.call(key, thing, type: type) end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb new file mode 100644 index 00000000000000..f9b5eda0c35df1 --- /dev/null +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::LoadBalancing::Callbacks do + + # Around each example, reset the state of the callbacks so that specs don't pollute state + around do |example| + logger_proc = described_class.logger_proc + metrics_host_gauge_proc = described_class.metrics_host_gauge_proc + track_exception_proc = described_class.track_exception_proc + set_wal_for_proc = described_class.set_wal_for_proc + get_wal_for_proc = described_class.get_wal_for_proc + del_wal_for_proc = described_class.del_wal_for_proc + check_feature_flag = described_class.check_feature_flag + + example.run + + described_class.configure! do |cb| + cb.logger_proc = logger_proc + cb.metrics_host_gauge_proc = metrics_host_gauge_proc + cb.track_exception_proc = track_exception_proc + cb.set_wal_for_proc = set_wal_for_proc + cb.get_wal_for_proc = get_wal_for_proc + cb.del_wal_for_proc = del_wal_for_proc + cb.check_feature_flag = check_feature_flag + end + end + context '#feature_enabled?' do + let(:check_flag) { ->(key, thing, type: nil) { false } } + before do + described_class.configure! do |cb| + cb.check_feature_flag = check_flag + end + end + it 'passes through feature flag calls for load_balancer_ feature flags' do + expect(check_flag).to receive(:call).with(:load_balancer_some_flag, anything, type: anything) + described_class.feature_enabled?(:load_balancer_some_flag) + end + + it 'raises an exception for non-load_balancer feature flags' do + expect { described_class.feature_enabled?(:other_flag) }.to raise_error(/Unsupported feature flag/) + end + end +end -- GitLab From 9c62f77057179d94e2b94a8163513331d0e57c62 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 18 Jun 2025 13:44:55 -0500 Subject: [PATCH 27/31] Fix rubocop --- .../lib/gitlab/database/load_balancing/callbacks.rb | 1 + .../gitlab/database/load_balancing/callbacks_spec.rb | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index 2585cfab4a02e7..a98a4126bd9a2c 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -41,6 +41,7 @@ def self.track_exception(ex) def self.feature_enabled?(key, thing = nil, type: nil) raise "Unsupported feature flag #{key}" unless key.to_s.start_with?("load_balancer_") + check_feature_flag&.call(key, thing, type: type) end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb index f9b5eda0c35df1..72c274f25eb219 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/callbacks_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' RSpec.describe Gitlab::Database::LoadBalancing::Callbacks do - # Around each example, reset the state of the callbacks so that specs don't pollute state around do |example| logger_proc = described_class.logger_proc @@ -26,13 +25,18 @@ cb.check_feature_flag = check_feature_flag end end - context '#feature_enabled?' do - let(:check_flag) { ->(key, thing, type: nil) { false } } + + describe '#feature_enabled?' do + # rubocop:disable Lint/UnusedBlockArgument -- type here mirrors the type kwarg in the real callback + let(:check_flag) { ->(_key, _thing, type: nil) { false } } + # rubocop:enable Lint/UnusedBlockArgument + before do described_class.configure! do |cb| cb.check_feature_flag = check_flag end end + it 'passes through feature flag calls for load_balancer_ feature flags' do expect(check_flag).to receive(:call).with(:load_balancer_some_flag, anything, type: anything) described_class.feature_enabled?(:load_balancer_some_flag) -- GitLab From 10c186de9d5dcf763e57b153a68ab879b821788c Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 16 Jul 2025 10:19:03 -0500 Subject: [PATCH 28/31] wip fixing rebase, possibly some rails72 changes --- .../gitlab/database/load_balancing/sticking.rb | 2 +- .../database/load_balancing/sticking_spec.rb | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb index 3c3a362bb168f7..5c6767657acb3f 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb @@ -65,7 +65,7 @@ def bulk_stick(namespace, ids) private def log_database_sticking_operations_enabled? - Feature.enabled?(:log_database_sticking_operations, Feature.current_pod) + Callbacks.feature_enabled?(:log_database_sticking_operations, :current_pod) end def capture_stick_logs(namespace, ids, location) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb index 699ffdb3e21682..4eb04e331bbae2 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb @@ -141,12 +141,12 @@ describe '#log_database_sticking_operations_enabled?' do it 'returns true when the feature flag is enabled' do - stub_feature_flags(log_database_sticking_operations: true) + stub_load_balancer_feature_flags(log_database_sticking_operations: true) expect(sticking.send(:log_database_sticking_operations_enabled?)).to be true end it 'returns false when the feature flag is disabled' do - stub_feature_flags(log_database_sticking_operations: false) + stub_load_balancer_feature_flags(log_database_sticking_operations: false) expect(sticking.send(:log_database_sticking_operations_enabled?)).to be false end end @@ -157,7 +157,7 @@ context 'when logging is enabled and namespace is user' do before do - stub_feature_flags(log_database_sticking_operations: true) + stub_load_balancer_feature_flags(log_database_sticking_operations: true) allow(sticking).to receive(:with_primary_write_location).and_yield(location) allow(sticking).to receive(:set_write_location_for) @@ -165,7 +165,7 @@ end it 'logs the sticking operation with correct parameters' do - expect(::Gitlab::Database::LoadBalancing::Logger).to receive(:info).with( + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info).with( event: :load_balancer_stick_logging, client_id: "#{namespace}/#{id}", stick_id: id, @@ -176,7 +176,7 @@ end it 'logs only the first ID for bulk sticking operations with correct parameters' do - expect(::Gitlab::Database::LoadBalancing::Logger).to receive(:info).with( + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).to receive(:info).with( event: :load_balancer_stick_logging, client_id: "#{namespace}/#{ids.first}", stick_id: ids.first, @@ -190,7 +190,7 @@ context 'when logging is disabled' do before do - stub_feature_flags(log_database_sticking_operations: false) + stub_load_balancer_feature_flags(log_database_sticking_operations: false) allow(sticking).to receive(:with_primary_write_location).and_yield(location) allow(sticking).to receive(:set_write_location_for) @@ -198,7 +198,7 @@ end it 'does not log anything' do - expect(::Gitlab::Database::LoadBalancing::Logger).not_to receive(:info) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:info) sticking.stick(namespace, id) end @@ -208,7 +208,7 @@ let(:namespace) { 'project' } before do - stub_feature_flags(log_database_sticking_operations: true) + stub_load_balancer_feature_flags(log_database_sticking_operations: true) allow(sticking).to receive(:with_primary_write_location).and_yield(location) allow(sticking).to receive(:set_write_location_for) @@ -216,7 +216,7 @@ end it 'does not log anything' do - expect(::Gitlab::Database::LoadBalancing::Logger).not_to receive(:info) + expect(::Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:info) sticking.bulk_stick(namespace, ids) end -- GitLab From cd1b55b14516538c35aaed0f75fb1fa7f721fa10 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 16 Jul 2025 10:39:56 -0500 Subject: [PATCH 29/31] finish fixing sticking logging code --- .../lib/gitlab/database/load_balancing/callbacks.rb | 2 +- .../lib/gitlab/database/load_balancing/sticking.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index a98a4126bd9a2c..fe9ed04cac8baf 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -40,7 +40,7 @@ def self.track_exception(ex) end def self.feature_enabled?(key, thing = nil, type: nil) - raise "Unsupported feature flag #{key}" unless key.to_s.start_with?("load_balancer_") + raise "Unsupported feature flag #{key}" unless key.to_s.start_with?("load_balancer_") || key.to_s == 'log_database_sticking_operations' check_feature_flag&.call(key, thing, type: type) end diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb index 5c6767657acb3f..20e08577365764 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/sticking.rb @@ -74,7 +74,7 @@ def capture_stick_logs(namespace, ids, location) id = Array(ids).first # Only log the first ID to reduce log volume for bulk operations - ::Gitlab::Database::LoadBalancing::Logger.info( + ::Gitlab::Database::LoadBalancing::Callbacks.logger.info( event: :load_balancer_stick_logging, client_id: "#{namespace}/#{id}", stick_id: id, -- GitLab From 7ba909f16cf7f160ab80c54e8c45585244309a3e Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Wed, 16 Jul 2025 14:51:57 -0500 Subject: [PATCH 30/31] Rubocop fixes --- .../lib/gitlab/database/load_balancing/callbacks.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb index fe9ed04cac8baf..3528079ecf4ba8 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/callbacks.rb @@ -40,7 +40,9 @@ def self.track_exception(ex) end def self.feature_enabled?(key, thing = nil, type: nil) - raise "Unsupported feature flag #{key}" unless key.to_s.start_with?("load_balancer_") || key.to_s == 'log_database_sticking_operations' + unless key.to_s.start_with?("load_balancer_") || key.to_s == 'log_database_sticking_operations' + raise "Unsupported feature flag #{key}" + end check_feature_flag&.call(key, thing, type: type) end -- GitLab From b58e6dc54ff69f2d13dcae98dc8dd8f4f00f45c3 Mon Sep 17 00:00:00 2001 From: Simon Tomlinson Date: Mon, 21 Jul 2025 16:06:36 -0500 Subject: [PATCH 31/31] Fix rubocop violations after rubocop update --- .../database/load_balancing/configuration.rb | 2 +- .../service_discovery/sampler.rb | 2 +- .../gitlab/database/load_balancing/setup.rb | 2 +- .../load_balancing/configuration_spec.rb | 14 +-- .../load_balancing/connection_proxy_spec.rb | 23 ++--- .../database/load_balancing/host_list_spec.rb | 2 +- .../database/load_balancing/host_spec.rb | 32 +++---- .../load_balancing/load_balancer_spec.rb | 40 ++++----- .../load_balancing/primary_host_spec.rb | 4 +- .../database/load_balancing/resolver_spec.rb | 12 +-- .../load_balancing/service_discovery_spec.rb | 30 +++---- .../load_balancing/session_map_spec.rb | 58 ++++++------ .../database/load_balancing/session_spec.rb | 90 +++++++++---------- .../database/load_balancing/setup_spec.rb | 2 +- .../load_balancing/srv_resolver_spec.rb | 10 +-- .../database/load_balancing/sticking_spec.rb | 12 +-- .../gitlab/database/load_balancing_spec.rb | 4 +- 17 files changed, 160 insertions(+), 179 deletions(-) diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb index 4bcc3fde99c0ba..1167c843ec1b72 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/configuration.rb @@ -37,7 +37,7 @@ def self.for_model(model) # 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, _| + config.service_discovery.each_key do |key| if (value = discover[key]) config.service_discovery[key] = value end diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb index cbc6bfd0bc579a..5bb4ae788ad08a 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/service_discovery/sampler.rb @@ -37,7 +37,7 @@ def sample(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| + addresses_by_host.each_value do |addresses| next if addresses.empty? selected_addresses << addresses.pop diff --git a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb index d5be4800c6d7f1..f9f848ebacd44c 100644 --- a/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb +++ b/gems/gitlab-database-load_balancing/lib/gitlab/database/load_balancing/setup.rb @@ -70,7 +70,7 @@ def load_balancer def setup_class_attribute(attribute, value) @model.class_attribute(attribute) - @model.public_send("#{attribute}=", value) # rubocop:disable GitlabSecurity/PublicSend + @model.public_send(:"#{attribute}=", value) # rubocop:disable GitlabSecurity/PublicSend end def active_record_base? diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb index 41534c17c06293..f8c4c5e8136c27 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/configuration_spec.rb @@ -112,26 +112,26 @@ allow(Gitlab::Database::LoadBalancing).to receive(:enabled).and_return(false) - expect(config.load_balancing_enabled?).to eq(false) + expect(config.load_balancing_enabled?).to be(false) end it 'returns true when hosts are configured' do config = described_class.new(ActiveRecord::Base, %w[foo bar]) - expect(config.load_balancing_enabled?).to eq(true) + expect(config.load_balancing_enabled?).to be(true) end it 'returns true when a service discovery record is configured' do config = described_class.new(ActiveRecord::Base) config.service_discovery[:record] = 'foo' - expect(config.load_balancing_enabled?).to eq(true) + expect(config.load_balancing_enabled?).to be(true) end it 'returns false when no hosts are configured and service discovery is disabled' do config = described_class.new(ActiveRecord::Base) - expect(config.load_balancing_enabled?).to eq(false) + expect(config.load_balancing_enabled?).to be(false) end end @@ -142,20 +142,20 @@ config = described_class.new(ActiveRecord::Base) config.service_discovery[:record] = 'foo' - expect(config.service_discovery_enabled?).to eq(false) + expect(config.service_discovery_enabled?).to be(false) end it 'returns true when a record is configured' do config = described_class.new(ActiveRecord::Base) config.service_discovery[:record] = 'foo' - expect(config.service_discovery_enabled?).to eq(true) + expect(config.service_discovery_enabled?).to be(true) end it 'returns false when no record is configured' do config = described_class.new(ActiveRecord::Base) - expect(config.service_discovery_enabled?).to eq(false) + expect(config.service_discovery_enabled?).to be(false) end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb index 7ee9d6114cc07c..b30fab6fe37594 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/connection_proxy_spec.rb @@ -145,8 +145,7 @@ let(:replica) { double(:connection) } before do - allow(session).to receive(:fallback_to_replicas_for_ambiguous_queries?).and_return(true) - allow(session).to receive(:use_primary?).and_return(false) + allow(session).to receive_messages(fallback_to_replicas_for_ambiguous_queries?: true, use_primary?: false) allow(replica).to receive(:transaction).and_yield allow(replica).to receive(:select) end @@ -178,9 +177,8 @@ let(:primary) { double(:connection) } before do - allow(session).to receive(:fallback_to_replicas_for_ambiguous_queries?).and_return(false) - allow(session).to receive(:use_replicas_for_read_queries?).and_return(false) - allow(session).to receive(:use_primary?).and_return(true) + allow(session).to receive_messages(fallback_to_replicas_for_ambiguous_queries?: false, + use_replicas_for_read_queries?: false, use_primary?: true) allow(primary).to receive(:transaction).and_yield allow(primary).to receive(:select) allow(primary).to receive(:insert) @@ -233,8 +231,7 @@ before do allow(Gitlab::Database::LoadBalancing::SessionMap).to receive(:current).with(load_balancer) .and_return(session) - allow(session).to receive(:fallback_to_replicas_for_ambiguous_queries?).and_return(true) - allow(session).to receive(:use_primary?).and_return(false) + allow(session).to receive_messages(fallback_to_replicas_for_ambiguous_queries?: true, use_primary?: false) end it 'runs the query on the replica' do @@ -265,8 +262,7 @@ context 'with a regular session' do it 'uses a secondary' do - allow(session).to receive(:use_primary?).and_return(false) - allow(session).to receive(:use_replicas_for_read_queries?).and_return(false) + allow(session).to receive_messages(use_primary?: false, use_replicas_for_read_queries?: false) expect(connection).to receive(:foo).with('foo') expect(load_balancer).to receive(:read).and_yield(connection) @@ -277,8 +273,7 @@ context 'with a regular session and forcing all reads to replicas' do it 'uses a secondary' do - allow(session).to receive(:use_primary?).and_return(false) - allow(session).to receive(:use_replicas_for_read_queries?).and_return(true) + allow(session).to receive_messages(use_primary?: false, use_replicas_for_read_queries?: true) expect(connection).to receive(:foo).with('foo') expect(load_balancer).to receive(:read).and_yield(connection) @@ -289,8 +284,7 @@ context 'with a session using the primary but forcing all reads to replicas' do it 'uses a secondary' do - allow(session).to receive(:use_primary?).and_return(true) - allow(session).to receive(:use_replicas_for_read_queries?).and_return(true) + allow(session).to receive_messages(use_primary?: true, use_replicas_for_read_queries?: true) expect(connection).to receive(:foo).with('foo') expect(load_balancer).to receive(:read).and_yield(connection) @@ -301,8 +295,7 @@ describe 'with a session using the primary' do it 'uses the primary' do - allow(session).to receive(:use_primary?).and_return(true) - allow(session).to receive(:use_replicas_for_read_queries?).and_return(false) + allow(session).to receive_messages(use_primary?: true, use_replicas_for_read_queries?: false) expect(connection).to receive(:foo).with('foo') diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb index 0f4e21bb6d5e48..1e2d9cf3063010 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_list_spec.rb @@ -132,7 +132,7 @@ host_list.shuffle expect(host_list.length).to eq(host_count) - expect(host_list.hosts).to contain_exactly(*all_hosts) + expect(host_list.hosts).to match_array(all_hosts) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb index 184b8def64b725..8b72484f283df0 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/host_spec.rb @@ -266,7 +266,7 @@ def wrapped_exception(wrapper, original) .to receive(:last_checked_at) .and_return(1.year.ago) - expect(host.check_replica_status?).to eq(true) + expect(host.check_replica_status?).to be(true) end it 'returns false when we do not need to check the replica status' do @@ -275,7 +275,7 @@ def wrapped_exception(wrapper, original) .to receive(:last_checked_at) .and_return(Time.zone.now) - expect(host.check_replica_status?).to eq(false) + expect(host.check_replica_status?).to be(false) end end end @@ -287,7 +287,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_below_threshold?) .and_return(true) - expect(host.replica_is_up_to_date?).to eq(true) + expect(host.replica_is_up_to_date?).to be(true) end end @@ -303,7 +303,7 @@ def wrapped_exception(wrapper, original) .to receive(:data_is_recent_enough?) .and_return(true) - expect(host.replica_is_up_to_date?).to eq(true) + expect(host.replica_is_up_to_date?).to be(true) end it 'returns false when the data is not recent enough' do @@ -311,7 +311,7 @@ def wrapped_exception(wrapper, original) .to receive(:data_is_recent_enough?) .and_return(false) - expect(host.replica_is_up_to_date?).to eq(false) + expect(host.replica_is_up_to_date?).to be(false) end end end @@ -330,7 +330,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(1) - expect(host.replication_lag_below_threshold?).to eq(true) + expect(host.replication_lag_below_threshold?).to be(true) end it 'returns false when the lag time exceeds the threshold' do @@ -338,7 +338,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(9000) - expect(host.replication_lag_below_threshold?).to eq(false) + expect(host.replication_lag_below_threshold?).to be(false) end it 'returns false when no lag time could be calculated' do @@ -346,7 +346,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(nil) - expect(host.replication_lag_below_threshold?).to eq(false) + expect(host.replication_lag_below_threshold?).to be(false) end context 'with the load_balancer_double_replication_lag_time feature flag enabled' do @@ -357,7 +357,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(121) - expect(host.replication_lag_below_threshold?).to eq(false) + expect(host.replication_lag_below_threshold?).to be(false) end it 'returns true when lag time is below the higher threshold' do @@ -365,7 +365,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(119) - expect(host.replication_lag_below_threshold?).to eq(true) + expect(host.replication_lag_below_threshold?).to be(true) end end @@ -377,14 +377,14 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_time) .and_return(3600) - expect(host.replication_lag_below_threshold?).to eq(true) + expect(host.replication_lag_below_threshold?).to be(true) end end end describe '#data_is_recent_enough?' do it 'returns true when the data is recent enough' do - expect(host.data_is_recent_enough?).to eq(true) + expect(host.data_is_recent_enough?).to be(true) end it 'returns false when the data is not recent enough' do @@ -399,7 +399,7 @@ def wrapped_exception(wrapper, original) .to receive(:query_and_release) .and_return({ 'diff' => diff }) - expect(host.data_is_recent_enough?).to eq(false) + expect(host.data_is_recent_enough?).to be(false) end it 'returns false when no lag size could be calculated' do @@ -407,7 +407,7 @@ def wrapped_exception(wrapper, original) .to receive(:replication_lag_size) .and_return(nil) - expect(host.data_is_recent_enough?).to eq(false) + expect(host.data_is_recent_enough?).to be(false) end end @@ -613,7 +613,7 @@ def wrapped_exception(wrapper, original) let(:diff_result) { [{ "diff" => 123 }] } it 'returns false' do - expect(host.caught_up?('foo')).to eq(false) + expect(host.caught_up?('foo')).to be(false) end end end @@ -625,7 +625,7 @@ def wrapped_exception(wrapper, original) .to receive(:connection) .and_raise(wrapped_error) - expect(host.caught_up?('foo')).to eq(false) + expect(host.caught_up?('foo')).to be(false) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb index 24bdb7ee6f1a93..babeac02ba2242 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/load_balancer_spec.rb @@ -125,8 +125,7 @@ def twice_wrapped_exception(top, middle, original) allow(lb).to receive(:host).and_return(host) allow(Rails.application.executor).to receive(:active?).and_return(true) - allow(host).to receive(:query_cache_enabled).and_return(false) - allow(host).to receive(:connection).and_return(connection) + allow(host).to receive_messages(query_cache_enabled: false, connection: connection) expect(host).to receive(:enable_query_cache!).once @@ -139,8 +138,7 @@ def twice_wrapped_exception(top, middle, original) allow(lb).to receive(:host).and_return(host) allow(Rails.application.executor).to receive(:active?).and_return(false) - allow(host).to receive(:query_cache_enabled).and_return(false) - allow(host).to receive(:connection).and_return(connection) + allow(host).to receive_messages(query_cache_enabled: false, connection: connection) expect(host).not_to receive(:enable_query_cache!) @@ -402,25 +400,25 @@ def twice_wrapped_exception(top, middle, original) it 'returns true for a connection error' do error = ActiveRecord::ConnectionNotEstablished.new - expect(lb.connection_error?(error)).to eq(true) + expect(lb.connection_error?(error)).to be(true) end it 'returns false for a missing database error' do error = ActiveRecord::NoDatabaseError.new - expect(lb.connection_error?(error)).to eq(false) + expect(lb.connection_error?(error)).to be(false) end it 'returns true for a wrapped connection error' do wrapped = wrapped_exception(ActiveRecord::StatementInvalid, ActiveRecord::ConnectionNotEstablished) - expect(lb.connection_error?(wrapped)).to eq(true) + expect(lb.connection_error?(wrapped)).to be(true) end it 'returns true for a wrapped connection error from a view' do wrapped = wrapped_exception(ActionView::Template::Error, ActiveRecord::ConnectionNotEstablished) - expect(lb.connection_error?(wrapped)).to eq(true) + expect(lb.connection_error?(wrapped)).to be(true) end it 'returns true for deeply wrapped/nested errors' do @@ -430,25 +428,25 @@ def twice_wrapped_exception(top, middle, original) ActiveRecord::ConnectionNotEstablished ) - expect(lb.connection_error?(top)).to eq(true) + expect(lb.connection_error?(top)).to be(true) end it 'returns true for an invalid encoding error' do error = RuntimeError.new('invalid encoding name: unicode') - expect(lb.connection_error?(error)).to eq(true) + expect(lb.connection_error?(error)).to be(true) end it 'returns false for errors not related to database connections' do error = RuntimeError.new - expect(lb.connection_error?(error)).to eq(false) + expect(lb.connection_error?(error)).to be(false) end it 'returns false for ActiveRecord errors without a cause' do error = ActiveRecord::RecordNotUnique.new - expect(lb.connection_error?(error)).to eq(false) + expect(lb.connection_error?(error)).to be(false) end end @@ -463,13 +461,13 @@ def twice_wrapped_exception(top, middle, original) end it 'returns for a serialization error' do - expect(lb.serialization_failure?(conflict_error.new)).to eq(true) + expect(lb.serialization_failure?(conflict_error.new)).to be(true) end it 'returns true for a wrapped error' do wrapped = wrapped_exception(ActionView::Template::Error, conflict_error) - expect(lb.serialization_failure?(wrapped)).to eq(true) + expect(lb.serialization_failure?(wrapped)).to be(true) end end @@ -478,7 +476,7 @@ def twice_wrapped_exception(top, middle, original) let(:hosts) { lb.host_list.hosts } let(:set_host) { request_cache[described_class::CACHE_KEY] } - subject { lb.select_up_to_date_host(location) } + subject(:select_up_to_date_host) { lb.select_up_to_date_host(location) } context 'when none of the replicas are caught up' do before do @@ -487,7 +485,7 @@ def twice_wrapped_exception(top, middle, original) end it 'returns NONE_CAUGHT_UP and does not update the host thread-local variable' do - expect(subject).to eq(described_class::NONE_CAUGHT_UP) + expect(select_up_to_date_host).to eq(described_class::NONE_CAUGHT_UP) expect(set_host).to be_nil end @@ -495,7 +493,7 @@ def twice_wrapped_exception(top, middle, original) expect(ActiveSupport::Notifications).to receive(:instrument) .with('caught_up_replica_pick.load_balancing', { result: false }) - subject + select_up_to_date_host end end @@ -506,7 +504,7 @@ def twice_wrapped_exception(top, middle, original) end it 'returns ANY_CAUGHT_UP and sets host thread-local variable' do - expect(subject).to eq(described_class::ANY_CAUGHT_UP) + expect(select_up_to_date_host).to eq(described_class::ANY_CAUGHT_UP) expect(set_host).to eq(hosts[0]) end @@ -514,7 +512,7 @@ def twice_wrapped_exception(top, middle, original) expect(ActiveSupport::Notifications).to receive(:instrument) .with('caught_up_replica_pick.load_balancing', { result: true }) - subject + select_up_to_date_host end end @@ -525,7 +523,7 @@ def twice_wrapped_exception(top, middle, original) end it 'returns ALL_CAUGHT_UP and sets host thread-local variable' do - expect(subject).to eq(described_class::ALL_CAUGHT_UP) + expect(select_up_to_date_host).to eq(described_class::ALL_CAUGHT_UP) expect(set_host).to be_in([hosts[0], hosts[1]]) end @@ -533,7 +531,7 @@ def twice_wrapped_exception(top, middle, original) expect(ActiveSupport::Notifications).to receive(:instrument) .with('caught_up_replica_pick.load_balancing', { result: true }) - subject + select_up_to_date_host end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb index d1e1b3eda46106..f5ef9a0767c286 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/primary_host_spec.rb @@ -62,7 +62,7 @@ describe '#online?' do it 'returns true' do - expect(host.online?).to eq(true) + expect(host.online?).to be(true) end end @@ -74,7 +74,7 @@ describe '#caught_up?' do it 'returns true' do - expect(host.caught_up?('foo')).to eq(true) + expect(host.caught_up?('foo')).to be(true) end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb index 4af36693383d54..cc7c38084df0b4 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/resolver_spec.rb @@ -16,14 +16,14 @@ end context 'when nameserver is not an IP' do - subject { described_class.new('localhost').resolve } + subject(:resolve_response) { described_class.new('localhost').resolve } it 'looks the nameserver up in the hosts file' do allow_next_instance_of(Resolv::Hosts) do |instance| allow(instance).to receive(:getaddress).with('localhost').and_return('127.0.0.2') end - expect(subject.address).to eq(ip_addr) + expect(resolve_response.address).to eq(ip_addr) end context 'when nameserver is not in the hosts file' do @@ -41,8 +41,8 @@ .with('localhost', Net::DNS::A) .and_return(packet) - expect(subject.address).to eq(ip_addr) - expect(subject.ttl).to eq(raw_ttl.seconds.from_now) + expect(resolve_response.address).to eq(ip_addr) + expect(resolve_response.ttl).to eq(raw_ttl.seconds.from_now) end context 'when nameserver is not in DNS' do @@ -55,7 +55,7 @@ .with('localhost', Net::DNS::A) .and_return(double(:packet, answer: [])) - expect { subject }.to raise_exception( + expect { resolve_response }.to raise_exception( described_class::UnresolvableNameserverError, 'could not resolve localhost' ) @@ -72,7 +72,7 @@ .with('localhost', Net::DNS::A) .and_raise(Net::DNS::Resolver::NoResponseError) - expect { subject }.to raise_exception( + expect { resolve_response }.to raise_exception( described_class::UnresolvableNameserverError, 'no response from DNS server(s)' ) diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb index cfa513c1c5c2b8..b89533d58bca0e 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/service_discovery_spec.rb @@ -33,7 +33,7 @@ describe '#initialize' do describe ':record_type' do - subject do + subject(:service_discovery) do described_class.new( load_balancer, nameserver: 'localhost', @@ -46,14 +46,14 @@ context 'with a supported type' do let(:record_type) { 'SRV' } - it { expect(subject.record_type).to eq Net::DNS::SRV } + it { expect(service_discovery.record_type).to eq Net::DNS::SRV } end context 'with an unsupported type' do let(:record_type) { 'AAAA' } it 'raises an argument error' do - expect { subject }.to raise_error(ArgumentError, 'Unsupported record type: AAAA') + expect { service_discovery }.to raise_error(ArgumentError, 'Unsupported record type: AAAA') end end end @@ -155,12 +155,7 @@ context 'when a refresh is necessary' do before do allow(service) - .to receive(:addresses_from_load_balancer) - .and_return(%w[localhost]) - - allow(service) - .to receive(:addresses_from_dns) - .and_return([10, [address_foo, address_bar]]) + .to receive_messages(addresses_from_load_balancer: %w[localhost], addresses_from_dns: [10, [address_foo, address_bar]]) end it 'refreshes the load balancer hosts' do @@ -175,12 +170,7 @@ context 'when a refresh is not necessary' do before do allow(service) - .to receive(:addresses_from_load_balancer) - .and_return(%w[localhost]) - - allow(service) - .to receive(:addresses_from_dns) - .and_return([10, %w[localhost]]) + .to receive_messages(addresses_from_load_balancer: %w[localhost], addresses_from_dns: [10, %w[localhost]]) end it 'does not refresh the load balancer hosts' do @@ -459,7 +449,7 @@ let(:refresh_thread) { nil } let(:last_run_timestamp) { nil } - subject { service.log_refresh_thread_interruption } + subject(:log_refresh_thread_interruption) { service.log_refresh_thread_interruption } context 'without refresh thread timestamp' do it 'does not log any interruption' do @@ -467,7 +457,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) - subject + log_refresh_thread_interruption end end @@ -477,7 +467,7 @@ it 'does not log if last run time plus delta is in future' do expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) - subject + log_refresh_thread_interruption end context 'with way past last run timestamp' do @@ -489,7 +479,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks.logger).not_to receive(:error) - subject + log_refresh_thread_interruption end it 'logs the error if the interruption was not logged before' do @@ -502,7 +492,7 @@ thread_backtrace: 'backtrace\nfoo' ) - subject + log_refresh_thread_interruption expect(service.refresh_thread_interruption_logged).to be_truthy end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb index 9de89d4d7b9c39..c3a230cd05917d 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_map_spec.rb @@ -37,7 +37,7 @@ context 'when using a rake runtime' do let(:pri_session) { Gitlab::Database::LoadBalancing::Session.new } - let(:pri_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } + let(:pri_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :primary) } before do sm = described_class.new @@ -55,13 +55,13 @@ end context 'when receiving invalid db type' do - let(:pri_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } - let(:invalid_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :invalid) } + let(:pri_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :primary) } + let(:invalid_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :invalid) } subject(:current) { described_class.current(lb) } context 'when db is invalid' do - let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :invalid) } + let(:lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :invalid) } it 'raises error' do expect do @@ -71,7 +71,7 @@ end context 'when db is primary' do - let(:lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :primary) } + let(:lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :primary) } it 'reports error without raising' do expect(Gitlab::Database::LoadBalancing::Callbacks).to receive(:track_exception) @@ -90,7 +90,7 @@ it 'clears instance from RequestStore' do described_class.clear_session - expect(RequestStore[described_class::CACHE_KEY]).to eq(nil) + expect(RequestStore[described_class::CACHE_KEY]).to be_nil end end @@ -143,15 +143,15 @@ end describe '.with_sessions' do - let(:main_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :main) } - let(:ci_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :ci) } - let(:sec_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :sec) } - let(:invalid_lb) { instance_double('Gitlab::Database::LoadBalancing::LoadBalancer', name: :invalid) } + let(:main_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :main) } + let(:ci_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :ci) } + let(:sec_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :sec) } + let(:invalid_lb) { instance_double(Gitlab::Database::LoadBalancing::LoadBalancer, name: :invalid) } - let(:main) { instance_double('ActiveRecord::Base', load_balancer: main_lb) } - let(:ci) { instance_double('ActiveRecord::Base', load_balancer: ci_lb) } - let(:sec) { instance_double('ActiveRecord::Base', load_balancer: sec_lb) } - let(:invalid) { instance_double('ActiveRecord::Base', load_balancer: invalid_lb) } + let(:main) { instance_double(ActiveRecord::Base, load_balancer: main_lb) } + let(:ci) { instance_double(ActiveRecord::Base, load_balancer: ci_lb) } + let(:sec) { instance_double(ActiveRecord::Base, load_balancer: sec_lb) } + let(:invalid) { instance_double(ActiveRecord::Base, load_balancer: invalid_lb) } let(:all_dbs) { [main, ci, sec] } let(:scoped_dbs) { [main, ci] } @@ -181,11 +181,11 @@ with_sessions.use_primary! scoped_dbs.each do |db| - expect(described_class.current(db.load_balancer).use_primary?).to eq(true) + expect(described_class.current(db.load_balancer).use_primary?).to be(true) end (all_dbs - scoped_dbs).each do |db| - expect(described_class.current(db.load_balancer).use_primary?).to eq(false) + expect(described_class.current(db.load_balancer).use_primary?).to be(false) end end end @@ -194,16 +194,16 @@ it 'applies use_primary to all scoped sessions' do with_sessions.use_primary do scoped_dbs.each do |db| - expect(described_class.current(db.load_balancer).use_primary?).to eq(true) + expect(described_class.current(db.load_balancer).use_primary?).to be(true) end (all_dbs - scoped_dbs).each do |db| - expect(described_class.current(db.load_balancer).use_primary?).to eq(false) + expect(described_class.current(db.load_balancer).use_primary?).to be(false) end end all_dbs.each do |db| - expect(described_class.current(db.load_balancer).use_primary?).to eq(false) + expect(described_class.current(db.load_balancer).use_primary?).to be(false) end end end @@ -216,13 +216,13 @@ end scoped_dbs.each do |db| - expect(described_class.current(db.load_balancer).performed_write?).to eq(true) - expect(described_class.current(db.load_balancer).use_primary?).to eq(false) + expect(described_class.current(db.load_balancer).performed_write?).to be(true) + expect(described_class.current(db.load_balancer).use_primary?).to be(false) end (all_dbs - scoped_dbs).each do |db| - expect(described_class.current(db.load_balancer).performed_write?).to eq(true) - expect(described_class.current(db.load_balancer).use_primary?).to eq(true) + expect(described_class.current(db.load_balancer).performed_write?).to be(true) + expect(described_class.current(db.load_balancer).use_primary?).to be(true) end end end @@ -232,16 +232,16 @@ it 'applies use_replicas_for_read_queries to all scoped sessions' do with_sessions.use_replicas_for_read_queries do scoped_dbs.each do |db| - expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to eq(true) + expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to be(true) end (all_dbs - scoped_dbs).each do |db| - expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to eq(false) + expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to be(false) end end all_dbs.each do |db| - expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to eq(false) + expect(described_class.current(db.load_balancer).use_replicas_for_read_queries?).to be(false) end end end @@ -250,16 +250,16 @@ it 'applies fallback_to_replicas_for_ambiguous_queries to all scoped sessions' do with_sessions.fallback_to_replicas_for_ambiguous_queries do scoped_dbs.each do |db| - expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to be(true) end (all_dbs - scoped_dbs).each do |db| - expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to be(false) end end all_dbs.each do |db| - expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(described_class.current(db.load_balancer).fallback_to_replicas_for_ambiguous_queries?).to be(false) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb index b83f175c0ccda6..a32b85f5905233 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/session_spec.rb @@ -9,11 +9,11 @@ instance.use_primary! - expect(instance.use_primary?).to eq(true) + expect(instance.use_primary?).to be(true) end it 'returns false when a secondary should be used' do - expect(described_class.new.use_primary?).to eq(false) + expect(described_class.new.use_primary?).to be(false) end it 'returns true when a write was performed' do @@ -21,7 +21,7 @@ instance.write! - expect(instance.use_primary?).to eq(true) + expect(instance.use_primary?).to be(true) end end @@ -36,7 +36,7 @@ it 'restores state after use' do expect { |blk| instance.use_primary(&blk) }.to yield_with_no_args - expect(instance.use_primary?).to eq(true) + expect(instance.use_primary?).to be(true) end end @@ -44,14 +44,14 @@ it 'restores state after use' do expect { |blk| instance.use_primary(&blk) }.to yield_with_no_args - expect(instance.use_primary?).to eq(false) + expect(instance.use_primary?).to be(false) end end it 'uses primary during block' do expect do |blk| instance.use_primary do - expect(instance.use_primary?).to eq(true) + expect(instance.use_primary?).to be(true) # call yield probe blk.to_proc.call @@ -64,7 +64,7 @@ instance.write! end - expect(instance.use_primary?).to eq(true) + expect(instance.use_primary?).to be(true) end end @@ -74,7 +74,7 @@ instance.write! - expect(instance.performed_write?).to eq(true) + expect(instance.performed_write?).to be(true) end end @@ -85,7 +85,7 @@ instance.ignore_writes { instance.write! } expect(instance).not_to be_using_primary - expect(instance.performed_write?).to eq true + expect(instance.performed_write?).to be true end it 'does not prevent using primary if an exception is raised' do @@ -108,31 +108,31 @@ it 'sets the flag inside the block' do expect do |blk| instance.use_replicas_for_read_queries do - expect(instance.use_replicas_for_read_queries?).to eq(true) + expect(instance.use_replicas_for_read_queries?).to be(true) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.use_replicas_for_read_queries?).to eq(false) + expect(instance.use_replicas_for_read_queries?).to be(false) end it 'restores state after use' do expect do |blk| instance.use_replicas_for_read_queries do instance.use_replicas_for_read_queries do - expect(instance.use_replicas_for_read_queries?).to eq(true) + expect(instance.use_replicas_for_read_queries?).to be(true) # call yield probe blk.to_proc.call end - expect(instance.use_replicas_for_read_queries?).to eq(true) + expect(instance.use_replicas_for_read_queries?).to be(true) end end.to yield_control - expect(instance.use_replicas_for_read_queries?).to eq(false) + expect(instance.use_replicas_for_read_queries?).to be(false) end context 'when primary was used before' do @@ -143,14 +143,14 @@ it 'sets the flag inside the block' do expect do |blk| instance.use_replicas_for_read_queries do - expect(instance.use_replicas_for_read_queries?).to eq(true) + expect(instance.use_replicas_for_read_queries?).to be(true) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.use_replicas_for_read_queries?).to eq(false) + expect(instance.use_replicas_for_read_queries?).to be(false) end end @@ -162,14 +162,14 @@ it 'sets the flag inside the block' do expect do |blk| instance.use_replicas_for_read_queries do - expect(instance.use_replicas_for_read_queries?).to eq(true) + expect(instance.use_replicas_for_read_queries?).to be(true) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.use_replicas_for_read_queries?).to eq(false) + expect(instance.use_replicas_for_read_queries?).to be(false) end end end @@ -180,31 +180,31 @@ it 'sets the flag inside the block' do expect do |blk| instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end it 'restores state after use' do expect do |blk| instance.fallback_to_replicas_for_ambiguous_queries do instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) # call yield probe blk.to_proc.call end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) end end.to yield_control - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end context 'when primary was used before' do @@ -213,18 +213,18 @@ end it 'uses primary during block' do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) expect do |blk| instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end end @@ -234,82 +234,82 @@ end it 'uses primary during block' do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) expect do |blk| instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) # call yield probe blk.to_proc.call end end.to yield_control - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end end context 'when primary was used inside the block' do it 'uses primary aterward' do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) instance.use_primary! - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end it 'restores state after use' do instance.fallback_to_replicas_for_ambiguous_queries do instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) instance.use_primary! - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end end context 'when a write was performed inside the block' do it 'uses primary aterward' do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) instance.write! - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end it 'restores state after use' do instance.fallback_to_replicas_for_ambiguous_queries do instance.fallback_to_replicas_for_ambiguous_queries do - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(true) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(true) instance.write! - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end - expect(instance.fallback_to_replicas_for_ambiguous_queries?).to eq(false) + expect(instance.fallback_to_replicas_for_ambiguous_queries?).to be(false) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb index 2e62dd0f95d443..98f80ba25aad77 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/setup_spec.rb @@ -156,7 +156,7 @@ def self.name end # Make load balancer to force init with a dedicated replicas connections - models.each do |_, model| + models.each_value do |model| described_class.new(model).tap do |subject| subject.configuration.hosts = [subject.configuration.db_config.host] subject.setup diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb index 27c8a0b7c26420..4ab17457255978 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/srv_resolver_spec.rb @@ -9,11 +9,11 @@ describe '#address_for' do let(:host) { 'patroni-02-db-gstg.node.east-us-2.consul.' } - subject { described_class.new(resolver, additional).address_for(host) } + subject(:address) { described_class.new(resolver, additional).address_for(host) } context 'when additional section contains an A record' do it 'returns an IP4 address' do - expect(subject).to eq(IPAddr.new('10.224.29.102')) + expect(address).to eq(IPAddr.new('10.224.29.102')) end end @@ -22,7 +22,7 @@ let(:additional) { dns_response_packet_from_fixture('a_with_aaaa_rr_in_additional_section').additional } it 'returns an IP6 address' do - expect(subject).to eq(IPAddr.new('2001:503:a83e::2:30')) + expect(address).to eq(IPAddr.new('2001:503:a83e::2:30')) end end @@ -35,7 +35,7 @@ end it 'returns an IP4 address' do - expect(subject).to eq(IPAddr.new('10.224.29.102')) + expect(address).to eq(IPAddr.new('10.224.29.102')) end end @@ -45,7 +45,7 @@ end it 'returns an IP6 address' do - expect(subject).to eq(IPAddr.new('2a00:1450:400e:80a::200e')) + expect(address).to eq(IPAddr.new('2a00:1450:400e:80a::200e')) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb index 4eb04e331bbae2..92de1a723a69d6 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing/sticking_spec.rb @@ -40,7 +40,7 @@ it 'returns true' do expect(load_balancer).not_to receive(:select_up_to_date_host) - expect(sticking.find_caught_up_replica(:user, 42)).to eq(true) + expect(sticking.find_caught_up_replica(:user, 42)).to be(true) end context 'when use_primary_on_empty_location is true' do @@ -50,7 +50,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).to receive(:use_primary!) - expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_empty_location: true)).to eq(false) + expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_empty_location: true)).to be(false) end end end @@ -63,7 +63,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks).to receive(:del_wal_for) .with("database-load-balancing/write-location/#{load_balancer.name}/user/42") - expect(sticking.find_caught_up_replica(:user, 42)).to eq(true) + expect(sticking.find_caught_up_replica(:user, 42)).to be(true) end end @@ -74,7 +74,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) - expect(sticking.find_caught_up_replica(:user, 42)).to eq(true) + expect(sticking.find_caught_up_replica(:user, 42)).to be(true) end end @@ -88,7 +88,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).to receive(:use_primary!) - expect(sticking.find_caught_up_replica(:user, 42)).to eq(false) + expect(sticking.find_caught_up_replica(:user, 42)).to be(false) end context 'when use_primary_on_failure is false' do @@ -96,7 +96,7 @@ expect(Gitlab::Database::LoadBalancing::Callbacks).not_to receive(:del_wal_for) expect(::Gitlab::Database::LoadBalancing::SessionMap.current(load_balancer)).not_to receive(:use_primary!) - expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_failure: false)).to eq(false) + expect(sticking.find_caught_up_replica(:user, 42, use_primary_on_failure: false)).to be(false) end end end diff --git a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb index fea7e434087908..fff6df47af9108 100644 --- a/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb +++ b/gems/gitlab-database-load_balancing/spec/gitlab/database/load_balancing_spec.rb @@ -28,7 +28,7 @@ allow(lb).to receive(:primary_only?).and_return(true) end - expect(described_class.primary_only?).to eq(true) + expect(described_class.primary_only?).to be(true) end it 'returns false if at least one has replicas' do @@ -36,7 +36,7 @@ allow(lb).to receive(:primary_only?).and_return(index != 0) end - expect(described_class.primary_only?).to eq(false) + expect(described_class.primary_only?).to be(false) end end -- GitLab