Pass **kwargs to the connection for LB defined methods [RUN ALL RSPEC] [RUN AS-IF-FOSS]
What does this MR do?
Resolves #336967 (closed)
How to setup and validate locally (strongly suggested)
Showing the issue
Maybe there is an easier way to demonstrate the issue, but I did that:
- Added a new spec into the
master
. I didn't transfer this spec to this branch, because it would be self-documenting. Basically, you could modify an existing spec, we just need to pass kwargs intotransaction
:
fromspec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb:116
:
end
### NEW TMP spec
context 'with keyword arguments' do
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(replica).to receive(:select)
end
it 'passes them to the connection' do
expect(proxy.load_balancer).to receive(:read).twice.and_yield(replica)
expect(replica).to receive(:transaction).with(joinable: false).and_yield
proxy.transaction(joinable: false) { proxy.select('true') }
end
end
### Existing code below...
context 'session fallbacks ambiguous queries to replicas' do
let(:replica) { double(:connection) }
- In
lib/gitlab/database/load_balancing/connection_proxy.rb:94
I checked the arguments received:
def read_using_load_balancer(name, args, &block)
if current_session.use_primary? &&
!current_session.use_replicas_for_read_queries?
@load_balancer.read_write do |connection|
connection.send(name, *args, &block)
end
else
@load_balancer.read do |connection|
p name
p args
p block
p connection
connection.send(name, *args, &block)
end
- It was:
:transaction
[{:joinable=>false}]
#<Proc:0x00007fd9092f7aa8>
#<Double :connection>
- Then I checked that on Ruby 3.0, we fail to execute that on real connection, in
rails c
:
[3] pry(main)> name = :transaction
=> :transaction
[4] pry(main)> args = [{:joinable=>false}]
=> [{:joinable=>false}]
[6] pry(main)> block = Proc.new {}
=> #<Proc:0x00007fe7476798d8 (pry):6>
[7] pry(main)> connection = ActiveRecord::Base.connection
[8] pry(main)> connection.send(name, *args, &block)
ArgumentError: wrong number of arguments (given 1, expected 0)
from /Users/lipton/.asdf/installs/ruby/3.0.2/lib/ruby/gems/3.0.0/gems/activerecord-6.1.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:313:in `transaction'
^ ^ ^
an issue in Ruby3
^ ^ ^
----
Works fine if it would be kwargs (next two strings are the same):
----
[10] pry(main)> connection.send(name, **(args.first), &block)
=> nil
[13] pry(main)> connection.send(name, joinable: false, &block)
=> nil
- While on Ruby 2.7, all would be fine:
--------------------------------------------------------------------------------
Ruby: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]
GitLab: 14.2.0-pre (742e2b297d7) EE
GitLab Shell: 13.19.1
PostgreSQL: 12.6
--------------------------------------------------------------------------------
Loading development environment (Rails 6.1.3.2)
Found plugin pry-shell, but could not require 'pry-shell'
cannot load such file -- pry-shell
[1] pry(main)> name = :transaction
=> :transaction
[2] pry(main)> args = [{:joinable=>false}]
=> [{:joinable=>false}]
[3] pry(main)> block = Proc.new {}
=> #<Proc:0x00007fc879026f68 (pry):3>
[4] pry(main)> connection = ActiveRecord::Base.connection; 0
=> 0
[5] pry(main)> connection.send(name, *args, &block)
=> nil
[6] pry(main)> connection.send(name, joinable: false, &block)
=> nil
Validating nothing is broken
I started the app locally with LB enabled. Any better ways to test it?
Does this MR meet the acceptance criteria?
Conformity
-
I have included changelog trailers, or none are needed. (Does this MR need a changelog?) -
I have added/updated documentation, or it's not needed. (Is documentation required?) -
I have properly separated EE content from FOSS, or this MR is FOSS only. (Where should EE code go?) -
I have added information for database reviewers in the MR description, or it's not needed. (Does this MR have database related changes?) -
I have self-reviewed this MR per code review guidelines. -
This MR does not harm performance, or I have asked a reviewer to help assess the performance impact. (Merge request performance guidelines) -
I have followed the style guides. -
This change is backwards compatible across updates, or this does not apply.
Availability and Testing
-
I have added/updated tests following the Testing Guide, or it's not needed. (Consider all test levels. See the Test Planning Process.) -
I have tested this MR in all supported browsers, or it's not needed. -
I have informed the Infrastructure department of a default or new setting change per definition of done, or it's not needed.
Security
N/A
Related to #336967 (closed)
Edited by Matthias Käppler