RailsRunner Issue in 3.3.24

Discussion in 'Bug Reports' started by compressed, Feb 8, 2009.

  1. compressed

    compressed New Member

    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.
  2. mistwang

    mistwang LiteSpeed Staff

    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. ppgengler

    ppgengler New Member

    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.
  4. mistwang

    mistwang LiteSpeed Staff

    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
    
  5. mistwang

    mistwang LiteSpeed Staff

    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. ppgengler

    ppgengler New Member

    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?
  7. mistwang

    mistwang LiteSpeed Staff

    You are right about the .reconnect.
    .clear_active_connections is for backward compatibility with earlier release.

Share This Page