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

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

Open
tom-kuca opened this issue Aug 9, 2011 · 9 comments
Open

Comments

@tom-kuca
Copy link

tom-kuca commented Aug 9, 2011

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
Copy link

rud commented Aug 24, 2011

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

@timcharper
Copy link
Contributor

Excellent Tom, thanks for the report!

DId you look at the wiki page?

https://github.com/timcharper/spork/wiki/Troubleshooting

Did it work to re-establish your connection during each run? Or do you have to close connections in the described before_fork hook?

If so, would you like to submit a pull request, or how do you want to go about contributing a fix? (if any fix required)

Tim

@tom-kuca
Copy link
Author

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
Copy link
Contributor

Thanks for the knowledge.

It still may be helpful to add a before_fork to enable workarounds for people who are stuck on older versions of rails. I am planning on splitting out spork-rails out of the spork gem so later versions of spork can be used with earlier versions of gems.

A note on the wiki Troubleshooting section would likely help those fellow postgres users. Do you want to add it or should I?

I'll take care of merging this… wait… where is it? Looks like you deleted your fork?

@juni0r
Copy link

juni0r commented Sep 28, 2011

So exactly how can I fix this?

@alan
Copy link

alan commented Oct 3, 2011

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

@juni0r
Copy link

juni0r commented Oct 5, 2011

Anyone?

@tom-kuca
Copy link
Author

tom-kuca commented Oct 6, 2011

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
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants