Don’t kill your app when using ActiveRecord in Rails Metal, release your database connections

In: Ruby|Ruby on Rails

15 Jun 2009

Rails Metal has been available on Rails since version 2.3 – it’s old news. But if you haven’t used it or heard about it, you can find out more about Rails Metal on the RoR weblog and on Jesse Newland’s blog.

So anyway, I am one of those laggards and only wrote a Rails Metal piece not too long ago for a Rails app on Wego.com in an effort to optimize some high volume requests. It looked something like this:

class Adamantine
  def self.call(env)
    if env['PATH_INFO'] =~ ROUTE_REGEX
      location = Location.find(1) # Use ActiveRecord.

      [200, { 'Content-Type' => 'text/html' }, [location.to_json]]
    else
      # Leave it to Rails to deal with the request.
      [404, { 'Content-Type' => 'text/html' }, ['Not Found']]
    end
  end
end

Notice the use of an ActiveRecord model. It ran for quite awhile, almost 30 minutes, in production until I started getting notification emails about “Too many open database connections” to the MySQL server! The change was promptly rolled back and there was no cheezburger for me.

dam it!

As it turns out, Rails doesn’t take care of certain things in Rails Metal pieces, including the releasing of connections back to the database connection pool. A bit of googling turned up this bug in Rails’ bug tracker (see Josh Peek’s comment about ActiveRecord::Base.clear_active_connections!).

I rewrote the Rails Metal piece to always ensure it clears any active database connections with ActiveRecord::Base.clear_active_connections!:

class Adamantine
  def self.call(env)
    if env['PATH_INFO'] =~ ROUTE_REGEX
      location = Location.find(1)

      [200, { 'Content-Type' => 'text/html' }, [location.to_json]]
    else
      # Leave it to Rails to deal with the request.
      [404, { 'Content-Type' => 'text/html' }, ['Not Found']]
    end
  ensure
    # Release the connections back to the pool.
    ActiveRecord::Base.clear_active_connections!
  end
end

Moral of the story: Don’t forget to release your database connections if you’re using ActiveRecord in your Rails Metal. Or even better, don’t use ActiveRecord in Rails Metal – you’re aiming for raw speed anyway right?

6 Responses to Don’t kill your app when using ActiveRecord in Rails Metal, release your database connections

Avatar

Double Shot #475 « A Fresh Cup

June 16th, 2009 at 6pm

[...] Don’t kill your app when using ActiveRecord in Rails Metal, release your database connections – Probably better is “Don’t use Active Record in Metal.” [...]

Avatar

Fabien JAKIMOWICZ

June 16th, 2009 at 11pm

I run in the same trouble when running a nanite agent on rails. But I used ActiveRecord::Base.connection_pool.release_connection to solve the problem.

Your solutions is cleaner, thanks !

Avatar

Alistair Holt

August 17th, 2009 at 12am

I’m not sure this is needed. Shouldn’t the ActiveRecord::ConnectionAdapters::ConnectionManagement middleware be doing this for you?

Avatar

Paul

February 23rd, 2010 at 6pm

@Alistair, the ActiveRecord::ConnectionAdapters::ConnectionManagement middleware is not hit when using Metal (unless you manually move around your middleware stack.

Avatar

Lanza

January 22nd, 2012 at 11pm

The cheezburger is a lie. The cheezburger is a lie…

Avatar

michael kors outlet coupons

August 20th, 2014 at 4am

Follow The Pace Of Fashion, Come In Our official michael kors handbags outlet locations website
online Shop To Buy michael kors handbags! We Can Supply
Big Discount!.

from:michael kors outlet coupons

Comment Form