RailsRunner Issue in 3.3.24

#1
OS: Ubuntu Hardy 8.04
DB: Postgres 8.3
Rails: 2.0.2

After upgrading to 3.3.24, my rails app failed to work, returning 500 Internal Server Error. After some hair-pulling, I tracked it down to this line:

Code:
ActiveRecord::Base.connection.disconnect! and @reconnect = true if defined?(ActiveRecord::Base)
Replacing it with
Code:
ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord::Base)
, (I think the older version of this line) fixed the issue.

Here's the trace from the logs:

/!\ FAILSAFE /!\ Sun Feb 08 17:01:56 -0500 2009
Status: 500 Internal Server Error
closed connection
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:257:in `reset'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:257:in `reconnect!'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract_adapter.rb:108:in `verify!'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:122:in `verify_active_connections!'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:121:in `each_value'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:121:in `verify_active_connections!'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:146:in `prepare_application'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:178:in `send!'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:178:in `run_callbacks'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:175:in `each'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:175:in `send!'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:175:in `run_callbacks'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:114:in `dispatch'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:126:in `dispatch_cgi'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/dispatcher.rb:9:in `dispatch'
/usr/local/lsws/fcgi-bin/RailsRunner.rb:32

Please advise.
 

mistwang

LiteSpeed Staff
#2
Looks like the new code does not compatible with certain earlier release of Rails.
Maybe add some code to detect the rails version and use corresponding code to close connections?

Any rails developer want to help on this?
 
#3
Our replacement

Hi,

We had a similar issue just recently and ended up replacing the quoted line with:

Code:
if defined?(ActiveRecord::Base)
  ActiveRecord::Base.connection.disconnect! 
  @reconnect = true 
  ActiveRecord::Base.establish_connection
end
So perhaps this is compatible with the older versions of rails? (We're using 2.2.2).

Its important to note that .establish_connection doesn't actually create the DB connection so there shouldn't be a perf cost there, it just preps the ActiveRecord class for the connection once litespeed forks for ruby.

It'd be nice to get feedback on whether this is the preferred method, and it'd be nice for the default litespeed install to handle this correctly, as it essentially means out of the box the app is broken, for postgre sql at least.
 

mistwang

LiteSpeed Staff
#4
How about this

Code:
if defined?(ActiveRecord::Base)
   if defined?(ActiveRecord::Base.clear_active_connections!)
      ActiveRecord::Base.clear_active_connections!
   else
      ActiveRecord::Base.connection.disconnect! 
      @reconnect = true 
      ActiveRecord::Base.establish_connection
   end
end
 

mistwang

LiteSpeed Staff
#5
Or

Code:
if defined?(ActiveRecord::Base)
   if defined?(ActiveRecord::Base.clear_active_connections!)
      ActiveRecord::Base.clear_active_connections!
   else
      ActiveRecord::Base.connection.disconnect! 
      ActiveRecord::Base.connection.reconnect!
   end
end

while LSAPI.accept != nil

    Dispatcher.dispatch
end
 
#6
First is better?

I think the second of those that uses .reconnect is worse because it opens the DB connection before the process forks into ruby thus incuring more cost; I think the .establish_connection is key because it makes the connection ready, but doesn't actual make any connection to the db.

What does the .clear_active_connections do?
 
Top