Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Second run of tests fails with #<PGError: no connection to the server> #134

Open
tom-kuca opened this Issue · 9 comments

6 participants

@tom-kuca

As the title says, the second run of any test fails when using Rails 3.1 application and PostgreSQL database.

Steps to reproduce:

  • launch spork with rails 3.* application
  • run any test (OK)
  • run one more test (fails with #<PGError: no connection to the server>)

The problem seems to be the same which Passenger and Resque already run into.

Spork forks the application with running database connection. The new, forked, thread closes the old connection and creates a new one, because using database connection in forked process is prohibited. But the newer versions of Rails use prepared statements and a query which deallocates them is executed when the database connection is closed. And this is the problem - spork forks application, the new forked thread closes the database connection and during that, a query to database is sent - and it fails, because the connection is invalid.

I solved it by creating a new before_fork hook, similar to each_run and after_each_run hooks. If the connection to the database is closed in before_fork hook, the tests run as expected. I'm not sure if this is the best solution, but it works fine for me.

I'm using Rails 3.1.0.rc5, PostgreSQL 9.0, Spork 0.9.0.rc8. But in my opinion, the issue not addicted to a any particular version.

Backtrace:

Exception encountered: #<PGError: no connection to the server
>
backtrace:

../active_record/connection_adapters/postgresql_adapter.rb:272:in `exec'
../active_record/connection_adapters/postgresql_adapter.rb:272:in `block in clear_cache!'
../active_record/connection_adapters/postgresql_adapter.rb:271:in `each_value'
../active_record/connection_adapters/postgresql_adapter.rb:271:in `clear_cache!'
../active_record/connection_adapters/postgresql_adapter.rb:286:in `reconnect!'
../active_record/connection_adapters/abstract_adapter.rb:167:in `verify!'
../active_record/connection_adapters/abstract/connection_pool.rb:324:in `block in checkout_and_verify'
../active_support/callbacks.rb:390:in `_run_checkout_callbacks'
../active_support/callbacks.rb:81:in `run_callbacks'
../active_record/connection_adapters/abstract/connection_pool.rb:323:in `checkout_and_verify'
../active_record/connection_adapters/abstract/connection_pool.rb:319:in `checkout_existing_connection'
../active_record/connection_adapters/abstract/connection_pool.rb:262:in `block (2 levels) in checkout'
../active_record/connection_adapters/abstract/connection_pool.rb:260:in `loop'
../active_record/connection_adapters/abstract/connection_pool.rb:260:in `block in checkout'
../ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
../active_record/connection_adapters/abstract/connection_pool.rb:259:in `checkout'
../active_record/connection_adapters/abstract/connection_pool.rb:161:in `connection'
../active_record/connection_adapters/abstract/connection_pool.rb:398:in `retrieve_connection'
../active_record/connection_adapters/abstract/connection_specification.rb:107:in `retrieve_connection'
../active_record/connection_adapters/abstract/connection_specification.rb:89:in `connection
...
@rud

Did you forget to attach a commit to this issue? Sounds like you already have the code locally. Please share :)

@timcharper
Owner
@tom-kuca

It's not possible to simply reestablish connection at each_run, because it's hard to clear the old connection. There probably exists some dirty way how the kill it, but thinks like ActiveRecord::Base.connection.disconnect! or ActiveRecord::Base.establish_connection fails.

However, the issue was solved just before a couple of days, see rails/rails@77e0bdd, the statement cache is now associated with process id.

I can cleanup my code and create a pull request but I think it's no longer needed. Close the issue if you feel it the same way.

@timcharper
Owner
@juni0r

So exactly how can I fix this?

@alan

Same problem here, is there a way to fix this?

@juni0r

Anyone?

@tom-kuca

It seems my previous fork is lost, i probably did it on my local machine. However I create a new one, which works for me. See tom-kuca@98de897

The commit adds a before fork hook which can be used to close the database connection to the database before the process is forked.

I use the patch with following code in spec/spec_helper.rb:

Spork.before_fork do
  # This code will be run each time you run your specs before the spork process if forked.
  ActiveRecord::Base.connection_pool.disconnect!
end

P.S. Sorry for delayed answer

@coryschires

I upgraded to the latest versions of rails and spork, which resolved the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.