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
  • Select an option

  • Save the-spectator/13ad4709c45cec99c2403be24f7570be to your computer and use it in GitHub Desktop.

Select an option

Save the-spectator/13ad4709c45cec99c2403be24f7570be to your computer and use it in GitHub Desktop.

Revisions

  1. @benoittgt benoittgt revised this gist Feb 26, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions rails_7_print_pool.rb
    Original file line number Diff line number Diff line change
    @@ -22,8 +22,8 @@ def internal_poll(timeout)
    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
    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

  2. @benoittgt benoittgt revised this gist Feb 26, 2025. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions rails_7_print_pool.rb
    Original file line number Diff line number Diff line change
    @@ -23,6 +23,7 @@ def internal_poll(timeout)
    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

  3. @benoittgt benoittgt revised this gist Feb 26, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion rails_7_print_pool.rb
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ def internal_poll(timeout)
    # Configure a very small connection pool
    ActiveRecord::Base.establish_connection(
    adapter: "postgresql",
    database: "playground",
    database: "playground", # create a database named "playground" in your local PostgreSQL
    pool: 2,
    checkout_timeout: 2
    )
  4. @benoittgt benoittgt revised this gist Feb 26, 2025. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions rails_7_print_pool.rb
    Original file line number Diff line number Diff line change
    @@ -22,6 +22,7 @@ def internal_poll(timeout)
    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
    puts "---- #{connection_mark} : Thread #{i}, status: #{t.status.inspect}, thread_info: #{t.inspect.split(' ', 2)[1].chop}"
    end

  5. @benoittgt benoittgt created this gist Feb 26, 2025.
    76 changes: 76 additions & 0 deletions rails_7_print_pool.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,76 @@
    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]"
    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",
    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