Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 524 Vote(s) - 3.52 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rails Resque workers fail with PGError: server closed the connection unexpectedly

#1
I have site running rails application and resque workers running in production mode, on Ubuntu 9.10, Rails 2.3.4, ruby-ee 2010.01, PostgreSQL 8.4.2

Workers constantly raised errors: PGError: server closed the connection unexpectedly.

My best guess is that master resque process establishes connection to db (e.g. authlogic does that when use User.acts_as_authentic), while loading rails app classes, and that connection becomes corrupted in fork()ed process (on exit?), so next forked children get kind of broken global ActiveRecord::Base.connection

I could reproduce very similar behaviour with this [sample code][1] imitating fork/processing in resque worker. (AFAIK, users of libpq recommended to recreate connections in forked process anyway, otherwise it's not safe )

But, the odd thing is that when I use pgbouncer or pgpool-II instead of direct pgsql connection, such errors do not appear.

So, the question is where and how should I dig to find out why it is broken for plain connection and is working with connection pools? Or reasonable workaround?

[1]:

[To see links please register here]

Reply

#2
When I created [Nestor][1], I had the same kind of problem. The solution was to re-establish the connection in the forked process. See the relevant code at

[To see links please register here]


From my _very_ limited look at Resque code, I believe a call to #establish_connection should be done right about here:

[To see links please register here]



[1]:

[To see links please register here]

Reply

#3
I had this issue with all of my Mailer classes and I needed to call `ActiveRecord::Base.verify_active_connections!` within the mailer methods in order to ensure a connection was made.
Reply

#4
Change Apache configuration and add

PassengerSpawnMethod conservative
Reply

#5
After doing a bit of research / trial and error. For anyone who is coming across the same issue. To clarify what gc mentioned.

Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }

Above code should be placed in: /lib/tasks/resque.rake

For example:

require 'resque/tasks'

task "resque:setup" => :environment do
ENV['QUEUE'] = '*'

Resque.after_fork do |job|
ActiveRecord::Base.establish_connection
end

end

desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"

Hope this helps someone, as much as it did for me.
Reply

#6
You cannot pass a libpq reference across a fork() (or to a new thread), unless your application takes very close care of not using it in conflicting ways. (Like, a mutex around every single attempt to use it, and you must never close it). This is the same for both direct connections and using pgbouncer. If it worked in pgbouncer, that was pure luck in missing a race condition for some reason, and will eventually break.

If your program uses forking, you *must* create the connection *after* the fork.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through