ActiveRecord does not release connections back to its connection pool
automatically. This patch forces ActiveRecord to release its own
connections.

Signed-off-by: Rein Henrichs <[email protected]>
---
 lib/puppet/rails.rb                          |    2 +
 lib/puppet/rails/activerecord_connections.rb |   50 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100644 lib/puppet/rails/activerecord_connections.rb

diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index 414b1bc..56e670b 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -78,6 +78,8 @@ module Puppet::Rails
   def self.init
     raise Puppet::DevError, "No activerecord, cannot init Puppet::Rails" 
unless Puppet.features.rails?
 
+    require 'lib/puppet/rails/activerecord_connections' # Patch for #3238
+
     connect
 
     unless ActiveRecord::Base.connection.tables.include?("resources")
diff --git a/lib/puppet/rails/activerecord_connections.rb 
b/lib/puppet/rails/activerecord_connections.rb
new file mode 100644
index 0000000..6281180
--- /dev/null
+++ b/lib/puppet/rails/activerecord_connections.rb
@@ -0,0 +1,50 @@
+module ActiveRecord
+  module ConnectionAdapters
+    class ConnectionPool
+      def cleanup_connection
+        return yield if Thread.current[:__AR__cleanup_connection]
+
+        begin
+          Thread.current[:__AR__cleanup_connection] = true
+          yield
+        ensure
+          release_connection
+          Thread.current[:__AR__cleanup_connection] = false
+        end
+      end
+    end
+  end
+end
+
+methods_to_wrap = {
+  (class<<ActiveRecord::Base;self;end) => [
+    :find, :find_every, :find_by_sql, :transaction, :count, :create, :delete, 
:count_by_sql,
+    :update, :destroy, :cache, :uncached, :quoted_table_name, :columns, 
:exists?, :update_all,
+    :increment_counter, :decrement_counter, :delete_all, :table_exists?, 
:update_counters, 
+  ],
+  ActiveRecord::Base => [:quoted_id, :valid?],
+  ActiveRecord::Associations::AssociationCollection => [:initialize, :find, 
:find_target, :load_target, :count],
+  ActiveRecord::Associations::HasAndBelongsToManyAssociation => [:create],
+  ActiveRecord::Associations::HasManyThroughAssociation => 
[:construct_conditions],
+  ActiveRecord::Associations::HasOneAssociation => [:construct_sql],
+  ActiveRecord::Associations::ClassMethods => [:collection_reader_method, 
:configure_dependency_for_has_many],
+  ActiveRecord::Calculations::ClassMethods => [:calculate],
+}
+methods_to_wrap[Test::Unit::TestSuite] = [:run]  if 
defined?(Test::Unit::TestSuite)
+
+methods_to_wrap.each do |klass, methods|
+  methods.each do |method|
+    klass.class_eval do
+      alias_method_chain method, :cleanup_connection do |target, punc|
+        eval %{
+          def #{target}_with_cleanup_connection#{punc}(*a, &b)
+            ActiveRecord::Base.connection_pool.cleanup_connection do
+              #{target}_without_cleanup_connection#{punc}(*a, &b)
+            end
+          end
+        }
+      end
+    end
+  end
+end
+
-- 
1.7.0.4

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to