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.
pgpHgoDY7737Q.pgp
Description: PGP signature
