Skip to content

Instantly share code, notes, and snippets.

@the-spectator
Forked from benoittgt/rails_7_print_pool.rb
Created March 2, 2025 17:48
Show Gist options
  • Save the-spectator/13ad4709c45cec99c2403be24f7570be to your computer and use it in GitHub Desktop.
Save the-spectator/13ad4709c45cec99c2403be24f7570be to your computer and use it in GitHub Desktop.
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails", "~> 7.2"
gem "pg"
end
require "active_record"
require "logger"
class ActiveRecord::ConnectionAdapters::ConnectionPool::ConnectionLeasingQueue
private
def internal_poll(timeout)
result = super
result
rescue ActiveRecord::ConnectionTimeoutError => e
puts "\n=== Connection Pool Timeout ==="
puts "\nPool size: #{ActiveRecord::Base.connection_pool.size}"
puts "Checked out connections: #{ActiveRecord::Base.connection_pool.connections.count}"
connection_owners = ActiveRecord::Base.connection_pool.connections.map(&:owner)
puts "\nThread list:"
Thread.list.each_with_index do |t, i|
connection_mark = connection_owners.include?(t) ? "[HAS CONNECTION]" : "[NO CONNECTION]"
connection_mark += "[CURRENT]" if t == Thread.current
connection_mark += "[MAIN]" if t == Thread.main
puts "---- #{connection_mark} : Thread #{i}, status: #{t.status.inspect}, thread_info: #{t.inspect.split(' ', 2)[1].chop}"
end
puts "\nCurrent thread: #{Thread.current.inspect}"
puts "\n=== End Debug Info ===\n"
raise e
end
end
# Configure a very small connection pool
ActiveRecord::Base.establish_connection(
adapter: "postgresql",
database: "playground", # create a database named "playground" in your local PostgreSQL
pool: 2,
checkout_timeout: 2
)
ActiveRecord::Base.logger = Logger.new(STDOUT)
# Create a simple table
ActiveRecord::Schema.define do
create_table :shipments, force: true do |t|
t.string :status
end
end
class Shipment < ActiveRecord::Base
end
def dangerous_threads
threads = []
# We duplicate code to report different lines in the stack trace
threads << Thread.new do
puts "Thread 1 starting..."
ActiveRecord::Base.connection.execute("select pg_sleep(5)")
end
threads << Thread.new do
puts "Thread 2 starting..."
ActiveRecord::Base.connection.execute("select pg_sleep(5)")
end
threads << Thread.new do
puts "Thread 2 starting..."
ActiveRecord::Base.connection.execute("select pg_sleep(5)")
end
threads.each(&:join)
end
puts "Connection pool size: #{ActiveRecord::Base.connection_pool.size}"
puts "Starting threads..."
dangerous_threads
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment