Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Stale connection in `DatabaseCleaner::ActiveRecord::Truncation#connection`

Open
#86 1 comment 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
postgresql, rails, ruby
Domain
database, testing

Research direction

Start at DatabaseCleaner::ActiveRecord::Truncation#clean and the strategy's @connection initialization described in the issue. Reproduce the connection-pool scenario with the provided RSpec example, then verify that repeated cleaning obtains a usable connection and that the tests no longer raise ActiveRecord::ConnectionNotEstablished.

Written by the indexing model from the issue text.

Description

Summary

Each instance of the DatabaseCleaner::ActiveRecord::Truncation strategy initializes its @connection field only once, using the ActiveRecord default connection. When the connection is first requested, ActiveRecord checks it out of the connection pool. Various hooks (e.g. ActiveRecord::TestFixtures.teardown_fixtures) can return the connection to the pool, but Truncation is unaware of this and holds onto the connection object.

If another thread checks the same connection out of the pool and calls disconnect!, then when Truncation tries to use the connection to clean the database, it will find that the connection is closed and raise an error.

Steps to reproduce:

  1. In a Rails/PostgreSQL project using RSpec, configure DatabaseCleaner as follows:

    RSpec.configure do |config|
      config.before(:suite) do
        DatabaseCleaner.strategy = :truncation
      end
    
      config.around do |example|
        DatabaseCleaner.cleaning do
          example.run
        end
      end
    end
    
  2. Write a test that, in a background thread, checks a connection out of the pool, removes it from the pool, and disconnects it, e.g.

     describe 'connection pooling' do
       def do_disconnect
         Thread.new do
           connection_pool = ActiveRecord::Base.connection_pool
           connection = connection_pool.checkout.tap do |conn|
             connection_pool.remove(conn)
           end
           begin
             connection.execute('SELECT 1')
           ensure
             connection.disconnect!
           end
         end
       end
     
       5.times do |i|
         it "test #{i}" do
           ActiveRecord::Base.connection.execute('SELECT 1')
           sleep(0.5)
           do_disconnect if i % 2 == 0
         end
       end
     end
    

    (This example is obviously quite contrived; I ran into the problem in a more realistic situation. See discussion in https://github.com/bensheldon/good_job/issues/849.)

Expected

  • Tests pass.

Actual

  • First couple of tests pass
  • Subsequent tests fail with ActiveRecord::ConnectionNotEstablished: connection is closed raised from DatabaseCleaner.cleaning via Truncation#clean

Workaround

Instead of using DatabaseCleaner.cleaning in an around block, explicitly call DatabaseCleaner.clean_with(:truncation) in an after(:each) block:

RSpec.configure do |config|
  config.after(:each) do
    DatabaseCleaner.clean_with(:truncation)
  end
end

Proposed fix

Get a fresh connection in each call to Truncation.clean -- I simulated this with a prepended module and it seems to work:

module Cleaninator
  def clean
    @connection = nil
    super
  end
end

class DatabaseCleaner::ActiveRecord::Truncation
  prepend Cleaninator
end
Dominant language
Ruby
Stars
76
Forks
76
PR merge metrics
No merged PRs in 30d

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from DatabaseCleaner/database_cleaner-active_record

All issues in DatabaseCleaner/database_cleaner-active_record

Similar issues

More Ruby issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.