Skip to content

Commit ea54939

Browse files
committed
Use a single lock for all connections
Followup: rails#46519 Followup: rails#46553 Fix: rails#45994 When using multiple database, `clear_query_caches_for_current_thread` goes over all connections pool and have to acquire locks one by one to clear each query cache. If two threads do this in a different order they might deadlock. By using a single lock for all connections we avoid this problem entirely and properly prevent the puma thread from competing with the main thread. As for previous PRs, it would be cleaner to have this lock around a Rack middleware, and to release it when calling Capybara primitives like `visit`. But we need a good chokepoint in Capybara for that, I need to explore that upstream.
1 parent 90a272a commit ea54939

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

activerecord/lib/active_record/connection_adapters/abstract_adapter.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,19 @@ def initialize(config_or_deprecated_connection, deprecated_logger = nil, depreca
172172
@verified = false
173173
end
174174

175+
THREAD_LOCK = ActiveSupport::Concurrency::ThreadLoadInterlockAwareMonitor.new
176+
private_constant :THREAD_LOCK
177+
178+
FIBER_LOCK = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
179+
private_constant :FIBER_LOCK
180+
175181
def lock_thread=(lock_thread) # :nodoc:
176182
@lock =
177183
case lock_thread
178184
when Thread
179-
ActiveSupport::Concurrency::ThreadLoadInterlockAwareMonitor.new
185+
THREAD_LOCK
180186
when Fiber
181-
ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
187+
FIBER_LOCK
182188
else
183189
ActiveSupport::Concurrency::NullLock
184190
end

0 commit comments

Comments
 (0)