Skip to content

Commit aa07544

Browse files
committed
Acquire semian resource for each retry in Active Record adapters
Previously, Active Record adapters would retry queries within the same acquisition attempt. Now, we wrap individual executions to ensure each retry is counted as one acquisition request.
1 parent 568d073 commit aa07544

File tree

2 files changed

+45
-20
lines changed

2 files changed

+45
-20
lines changed

lib/semian/activerecord_adapter.rb

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,6 @@ def initialize(*options)
5454
super
5555
end
5656

57-
if ActiveRecord.version >= Gem::Version.new("8.2.a")
58-
def execute_intent(intent)
59-
return super if self.class.query_allowlisted?(intent.processed_sql)
60-
61-
acquire_semian_resource(adapter: semian_adapter_name, scope: :query) do
62-
super
63-
end
64-
end
65-
else
66-
def raw_execute(sql, *args, **kwargs, &block)
67-
if self.class.query_allowlisted?(sql)
68-
super
69-
else
70-
acquire_semian_resource(adapter: semian_adapter_name, scope: :query) do
71-
super(sql, *args, **kwargs, &block)
72-
end
73-
end
74-
end
75-
end
76-
7757
def active?
7858
acquire_semian_resource(adapter: semian_adapter_name, scope: :ping) do
7959
super
@@ -110,6 +90,26 @@ def connect(*args)
11090
end
11191
end
11292

93+
if ActiveRecord.version >= Gem::Version.new("8.2.a")
94+
def perform_query(raw_connection, intent)
95+
return super if self.class.query_allowlisted?(intent.processed_sql)
96+
97+
acquire_semian_resource(adapter: semian_adapter_name, scope: :query) do
98+
super
99+
end
100+
end
101+
else
102+
def raw_execute(sql, *args, **kwargs, &block)
103+
if self.class.query_allowlisted?(sql)
104+
super
105+
else
106+
acquire_semian_resource(adapter: semian_adapter_name, scope: :query) do
107+
super(sql, *args, **kwargs, &block)
108+
end
109+
end
110+
end
111+
end
112+
113113
def semian_adapter_name
114114
raise NotImplementedError, "#{self.class} must implement an `semian_adapter_name` method"
115115
end

test/adapters/activerecord_adapter_shared_tests.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,31 @@ def test_circuit_open_errors_do_not_trigger_the_circuit_breaker
347347
end
348348
end
349349

350+
def test_semian_counts_each_retry_attempt_individually
351+
@adapter = new_adapter(
352+
connection_retries: 1,
353+
semian: SEMIAN_OPTIONS.merge(error_threshold: 3),
354+
)
355+
@adapter.connect!
356+
357+
query_acquisition_count = 0
358+
subscriber = Semian.subscribe do |event, _resource, scope, _adapter|
359+
if event == :success && scope == :query
360+
query_acquisition_count += 1
361+
end
362+
end
363+
364+
# Close the raw connection to trigger a retryable connection error
365+
@adapter.send(:raw_connection).close
366+
367+
value = @adapter.query_value("SELECT 1;")
368+
369+
assert_equal(2, value)
370+
assert_equal(2, query_acquisition_count)
371+
ensure
372+
Semian.unsubscribe(subscriber)
373+
end
374+
350375
private
351376

352377
def adapter_class

0 commit comments

Comments
 (0)