Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: ActiveRecord::ConnectionTimeoutError (MAYBE-RAILS-D0) #1686

Closed
wants to merge 1 commit into from

Conversation

revise-dev[bot]
Copy link

@revise-dev revise-dev bot commented Jan 24, 2025

The ActiveRecord::ConnectionTimeoutError occurs when the application runs out of available database connections in the connection pool. The error indicates that all connections were in use for more than 5 seconds when a new connection was requested.

Looking at the application architecture:

  1. Puma is configured to run with multiple threads (RAILS_MAX_THREADS=3 by default)
  2. GoodJob background job processor is running with multiple queues:
    • 1 thread for latency_low
    • 2 threads for latency_low,latency_medium
    • 1 thread for latency_low,latency_medium,latency_high
    • 1 thread for catch-all queue
    • Plus additional threads for job listener, cron, and executor (3 threads)

The current pool size of 11 is insufficient because:

  • Each Puma thread needs a connection (3 connections)
  • GoodJob needs 8 connections (5 queue threads + 3 management threads)
  • Additional connections may be needed for other concurrent operations

Increasing the pool size to 16 provides:

  • 3 connections for Puma threads
  • 8 connections for GoodJob
  • 5 additional connections as buffer for peaks in concurrent activity

This change aligns with the application's concurrent processing needs while maintaining a reasonable buffer to prevent connection timeouts during normal operation.

Test plan:

  1. Test concurrent web requests:
RSpec.describe "Database Connection Pool", type: :system do
  it "handles multiple concurrent requests without connection timeout" do
    allow(ActiveRecord::Base.connection_pool).to receive(:size).and_return(16)
    
    threads = 10.times.map do
      Thread.new do
        Account.transaction do
          Account.first
          sleep 0.5 # Simulate work
        end
      end
    end
    
    expect { threads.each(&:join) }.not_to raise_error
  end
end
  1. Test background job concurrency:
RSpec.describe "Background Job Concurrency", type: :job do
  it "processes multiple jobs simultaneously without connection timeout" do
    jobs = 10.times.map do
      TestJob.perform_later
    end
    
    expect {
      GoodJob.perform_inline
    }.not_to raise_error
  end
end

Tip

You can make revisions or ask questions of Revise.dev by using /revise in any comment or review!

  • /revise Add a comment above the method to explain why we're making this change.
  • /revise Why did you choose to make this change specifically?

Important

If something doesn't look right, click to retry this interaction.

@zachgoll zachgoll closed this Jan 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant