Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions activerecord/test/cases/test_case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,18 @@ def check_connection_leaks
end
end

pool.reap
pool.connections.each do |conn|
if conn.in_use?
if conn.owner != Fiber.current && conn.owner != Thread.current
leaked_conn << [conn.owner, conn.owner.backtrace]
conn.owner&.kill
# Avoid racing the pool reaper while it is performing maintenance.
pool.reaper_lock do
pool.reap
pool.connections.each do |conn|
if conn.in_use?
if conn.owner != Fiber.current && conn.owner != Thread.current
leaked_conn << [conn.owner, conn.owner.backtrace]
conn.owner&.kill
end
conn.steal!
pool.checkin(conn)
end
conn.steal!
pool.checkin(conn)
end
end
end
Expand Down
50 changes: 50 additions & 0 deletions activerecord/test/cases/test_case_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

require "cases/helper"

module ActiveRecord
class TestCaseLeakCheckTest < ActiveRecord::TestCase
include WaitForTestHelper

self.use_transactional_tests = false

def test_check_connection_leaks_does_not_report_connections_held_for_reaper_maintenance
pool = ActiveRecord::Base.connection_pool

conn = ActiveRecord::Base.lease_connection
conn.select_value("SELECT 1")
ActiveRecord::Base.connection_handler.clear_active_connections!

assert_not_nil conn

maintenance_started = Concurrent::Event.new

maintenance_thread = Thread.new do
Thread.current.name = "AR Pool Reaper"

pool.reaper_lock do
pool.send(:checkout_for_maintenance, conn)
maintenance_started.set
sleep 0.2
pool.send(:return_from_maintenance, conn)
end
end

assert maintenance_started.wait(1), "maintenance thread did not start"
wait_for(message: "connection was not checked out for maintenance") do
conn.in_use? && conn.owner != ActiveSupport::IsolatedExecutionState.context
end
Comment thread
curi marked this conversation as resolved.

assert_nothing_raised do
check_connection_leaks
end
ensure
maintenance_thread&.join

if conn&.in_use?
conn.steal!
pool.checkin(conn)
end
end
end
end