You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
In a Rails/PostgreSQL project using RSpec, configure DatabaseCleaner as follows:
@dmolesUC Thanks a lot! Your workaround saved my life! We use DatabaseCleaner in test API for end-to-end testing. Same issue - connection is closed after ~5 mins.
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, butTruncation
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 whenTruncation
tries to use the connection to clean the database, it will find that the connection is closed and raise an error.Steps to reproduce:
In a Rails/PostgreSQL project using RSpec, configure
DatabaseCleaner
as follows: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.
(This example is obviously quite contrived; I ran into the problem in a more realistic situation. See discussion in Fix flakey async test thread error bensheldon/good_job#849.)
Expected
Actual
ActiveRecord::ConnectionNotEstablished: connection is closed
raised fromDatabaseCleaner.cleaning
viaTruncation#clean
Workaround
Instead of using
DatabaseCleaner.cleaning
in anaround
block, explicitly callDatabaseCleaner.clean_with(:truncation)
in anafter(:each)
block:Proposed fix
Get a fresh connection in each call to
Truncation.clean
-- I simulated this with a prepended module and it seems to work:The text was updated successfully, but these errors were encountered: