Rein Henrichs wrote:
> ActiveRecord does not release connections back to its connection pool
> automatically. This patch forces ActiveRecord to release its own
> connections.

Excellent.  This looks like a lot like ticket #3693, which I filed
later, apparently failing to find #3238 when I searched.  It would be
great if this was able to fix things on older rails.

> 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

Shouldn't this be "require 'puppet/..." (no lib/ prefix) ?

> 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
> +

After changing the above from lib/puppet/ to puppet/, I get this error
after restarting puppetmasterd and running puppetd:

err: Could not retrieve catalog from remote server: Error 400 on
SERVER: undefined method `count' for class
`ActiveRecord::Associations::AssociationCollection'

Removing :count from line 26 of activerecord_connections.rb and
restarting puppetmasterd, I then get:

err: Could not retrieve catalog from remote server: Error 400 on
SERVER: undefined method `connection_pool' for
ActiveRecord::Base:Class

from a puppetd run.  Did I butcher up the patch or is this not
destined to work on rails-2.1?  (And, FWIW, rails-2.1 is the only
place I have the issue.  Looks like other folks in the ticket
suggested that updating to rails >= 2.2 solved it for them too.)

This is on a CentOS 5 system with puppet-2.6.2rc1.

The full puppetmasterd trace:

info: Connecting to mysql database: puppet
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1672:in
 `method_missing'
(eval):3:in `columns'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1162:in
 `column_names'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1175:in
 `column_methods_hash'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1719:in
 `all_attributes_exists?'
/usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `all?'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1719:in
 `each'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1719:in
 `all?'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1719:in
 `all_attributes_exists?'
/usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1618:in
 `method_missing'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/facts/active_record.rb:30:in 
`save'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:256:in `save'
/usr/lib/ruby/site_ruby/1.8/puppet/node/facts.rb:15:in `save'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:64:in `save'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:25:in 
`extract_facts_from_request'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/catalog/compiler.rb:30:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector/indirection.rb:193:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/indirector.rb:50:in `find'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/handler.rb:101:in `do_find'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/handler.rb:68:in `send'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/handler.rb:68:in `process'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick/rest.rb:24:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:45:in `listen'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `call'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:42:in `listen'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:41:in `initialize'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:41:in `new'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:41:in `listen'
/usr/lib/ruby/1.8/thread.rb:135:in `synchronize'
/usr/lib/ruby/site_ruby/1.8/puppet/network/http/webrick.rb:38:in `listen'
/usr/lib/ruby/site_ruby/1.8/puppet/network/server.rb:127:in `listen'
/usr/lib/ruby/site_ruby/1.8/puppet/network/server.rb:142:in `start'
/usr/lib/ruby/site_ruby/1.8/puppet/daemon.rb:124:in `start'
/usr/lib/ruby/site_ruby/1.8/puppet/application/master.rb:114:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/master.rb:46:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:393:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:287:in `run'
/usr/sbin/puppetmasterd:4
err: undefined method `connection_pool' for ActiveRecord::Base:Class

-- 
Todd        OpenPGP -> KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Grant me the senility to forget the people I never liked anyway, the
good fortune to run into the ones I do, and the eyesight to tell the
difference.

Attachment: pgpHgoDY7737Q.pgp
Description: PGP signature

Reply via email to