coderrr

January 12, 2009

Rails 2.2 ActiveRecord connection cleanup

Filed under: concurrency, rails, ruby — Tags: , , — coderrr @ 8:29 pm

I just wanted to go over the different ways Rails 2.2 can clean up your DB connections.

1. ActiveRecord::Base.clear_reloadable_connections!
If you don’t have cache_classes set to true, which means you are probably in development mode, then Rails will call ActiveRecord::Base.clear_reloadable_connections! after every request.

      def clear_reloadable_connections!
        @reserved_connections.each do |name, conn|
          checkin conn
        end
        @reserved_connections = {}
        @connections.each do |conn|
          conn.disconnect! if conn.requires_reloading?
        end
        @connections = []
      end

So this code checks in ALL connections and then disconnects ALL connections which requires_reloading? which seems to be pretty much return true for all DB adapters.

2. ActiveRecord::Base.clear_active_connections!

Unless the request is coming from a testing context this will be called after every request.

      def clear_active_connections!
        @connection_pools.each_value {|pool| pool.release_connection }
      end

      def release_connection
        conn = @reserved_connections.delete(current_connection_id)
        checkin conn if conn
      end

This code checks in the connection being used by the current thread back into the connection pool. It repeats this if you are using multiple connection pools. It will not disconnect the connection. In development mode, since every connection was already checked in and disconnected, this method should do nothing. In production mode it is the method responsible for checking in each thread’s connection after each request.

3. ActiveRecord::Base.clear_stale_cached_connections!

This method is not called by Rails but it is there for you to use.

      def clear_stale_cached_connections!
        remove_stale_cached_threads!(@reserved_connections) do |name, conn|
          checkin conn
        end
      end

This will go through and checkin any connections which were assigned to dead threads. It will not disconnect the connection. This method is safe to call whenever you want.

4. ActiveRecord::Base.verify_active_connections!

In 2.1 and before this was called before every request. In Rails 2.2 it is not called but it is there for you to use.

      def verify_active_connections! #:nodoc:
        clear_stale_cached_connections!
        @connections.each do |connection|
          connection.verify!
        end
      end

This method first calls the method which we just went over. It then verifies that every connection is still alive. If it is not, it will reconnect it. The way it checks if the connection is still alive is adapter-specific, but in MySQL and PostgreSQL it may actually attempt to send a query through the connection.

That means this method is NOT safe to call unless you can call it only when you know there are no active queries on the DB. Meaning you have all your DB access synchronized which, unless you are running in a single threaded Rails context, is usually never.

The verification and reconnection of each connection is pretty pointless now since every connection is verified right before it is checked out of the connection pool:

      def checkout_new_connection
        c = new_connection
        @connections << c
        checkout_and_verify(c)
      end

      def checkout_existing_connection
        c = (@connections - @checked_out).first
        checkout_and_verify(c)
      end

Hope someone finds this useful.

8 Comments »

  1. This is an interesting read, thanks for posting. I’m interested in Rails db connection pooling.

    Comment by Alex Kane — January 13, 2009 @ 3:06 am

  2. Hey,
    I’m getting a ton of StatementInvalid errors, apparently because of stale DB connections (to mysql). I found this post (http://www.ruby-forum.com/topic/123472) which recommended a monkey patch to force the renewal of some of the stale connections. What do you think is the best way to fix this? Thanks for your help, -nick

    Comment by Nick — January 30, 2009 @ 6:53 am

  3. Hey Nick

    Yea a monkeypatch (like the one is this post https://coderrr.wordpress.com/2009/01/08/activerecord-threading-issues-and-resolutions/) will work fine, if your issue is just mysql timing out after it’s ‘wait_timeout’ value.

    Comment by coderrr — January 31, 2009 @ 10:38 am

  4. [...] https://coderrr.wordpress.com/2009/01/12/rails-22-activerecord-connection-cleanup/ Possibly related posts: (automatically generated)Frameworks: Light on the SQL, Pleasethe scheduler and the active_recordActiveRecord with Multiple Databases [...]

    Pingback by Ruby: ActiveRecord « Rudimentary Art of Programming & Development — April 23, 2009 @ 5:19 pm

  5. Very useful!

    (Off-topic CSS gripe.)

    Your code samples are formatted in such a way that they are difficult to read in anything but Firefox. :)

    The font-size is 12pt, but the line height is 14px, which causes the lines to overlap one another awkwardly.

    Comment by eh — April 23, 2009 @ 6:04 pm

  6. Hey thanks a lot for mentioning that

    should be fixed now!

    Comment by coderrr — April 23, 2009 @ 8:14 pm

  7. VERY useful, thanks.

    I actually start my own threads from within a Rails app, which more or less works — but I need to be rather cognizant of what AR is doing with my threads to make sure I’m working properly. I had gotten pretty comfortable with it, and then it changed completely in 2.2. This is so very useful to me, thanks!

    Comment by Jonathan Rochkind — April 29, 2009 @ 10:34 pm

  8. Great post. I was checking continuously this blog and I am impressed! Extremely helpful info particularly the last part :) I care for such info a lot. I was seeking this particular info for a very long time. Thank you and best of luck.

    Comment by Dwain Quella — June 23, 2012 @ 6:03 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Customized Silver is the New Black Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: