+1 On Sun, 2011-06-05 at 09:12 +0100, R.I.Pienaar wrote: > This allows rubygems to be used to extend or override puppet behavior. > > Unfortunately the features system uses the autoloader so checking for > the rubygems feature causes a call loop. It's possible that a more > elegant way to avoid this exist rather than just checking the @path > but this did what I needed to do. > > Without caching the directories the tests would take forever to run > and eventually crash my server. Caching seems to avoid the biggest > of the performance hit. > > Signed-off-by: R.I.Pienaar <r...@devco.net> > --- > Local-branch: feature/master/7788 > lib/puppet/configurer.rb | 5 +++-- > lib/puppet/parser/compiler.rb | 1 + > lib/puppet/util/autoload.rb | 19 +++++++++++++++++-- > spec/unit/util/autoload_spec.rb | 10 +++++++++- > 4 files changed, 30 insertions(+), 5 deletions(-) > > diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb > index cfeb73a..00c3b18 100644 > --- a/lib/puppet/configurer.rb > +++ b/lib/puppet/configurer.rb > @@ -156,9 +156,10 @@ class Puppet::Configurer > return > end > ensure > - # Make sure we forget the retained module_directories of any autoload > - # we might have used. > + # Make sure we forget the retained module_directories and gem search > + # path of any autoload we might have used. > Thread.current[:env_module_directories] = nil > + Thread.current[:gemsearch_directories] = nil > > # Now close all of our existing http connections, since there's no > # reason to leave them lying open. > diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb > index c1daade..68498ad 100644 > --- a/lib/puppet/parser/compiler.rb > +++ b/lib/puppet/parser/compiler.rb > @@ -22,6 +22,7 @@ class Puppet::Parser::Compiler > # stick until the next entry to this function. > Thread.current[:known_resource_types] = nil > Thread.current[:env_module_directories] = nil > + Thread.current[:gemsearch_directories] = nil > > # ...and we actually do the compile now we have caching ready. > new(node).compile.to_resource > diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb > index 6537a4a..e61f4cd 100644 > --- a/lib/puppet/util/autoload.rb > +++ b/lib/puppet/util/autoload.rb > @@ -124,9 +124,24 @@ class Puppet::Util::Autoload > searchpath.map { |dir| Dir.glob("#{dir}/*.rb") }.flatten > end > > - # The list of directories to search through for loadable plugins. > + # features uses the autoloader which causes a loop so avoid trying to > + # ask Gem for its path during feature loading. > + # > + # We're using a per-thread cache based on the code in #module_directories. > + def gemsearchpaths > + unless @path == "puppet/feature" > + if Puppet.features.rubygems? > + return Thread.current[:gemsearch_directories] ||= Gem.all_load_paths > + end > + end > + > + return [] > + end > + > + # The list of directories to search through for loadable plugins. We > search gem paths first > + # so that people can use the gem packages to override core puppet features > if they wish. > def searchpath(env=nil) > - search_directories(env).uniq.collect { |d| File.join(d, @path) > }.find_all { |d| FileTest.directory?(d) } > + [gemsearchpaths, search_directories(env)].flatten.uniq.collect { |d| > File.join(d, @path) }.find_all { |d| FileTest.directory?(d) } > end > > def module_directories(env=nil) > diff --git a/spec/unit/util/autoload_spec.rb b/spec/unit/util/autoload_spec.rb > index d61b768..e962b1e 100755 > --- a/spec/unit/util/autoload_spec.rb > +++ b/spec/unit/util/autoload_spec.rb > @@ -51,13 +51,21 @@ describe Puppet::Util::Autoload do > @autoload.search_directories.should == %w{/one /two /libdir1 > /lib/dir/two /third/lib/dir} + $LOAD_PATH > end > > + it "should not try to merge rubygems dirs when called from the feature > system" do > + @autoload = Puppet::Util::Autoload.new("foo", "puppet/feature") > + Puppet.features.expects(:rubygems?).never > + @autoload.gemsearchpaths > + end > + > it "should include in its search path all of the unique search > directories that have a subdirectory matching the autoload path" do > @autoload = Puppet::Util::Autoload.new("foo", "loaddir") > @autoload.expects(:search_directories).returns %w{/one /two /three > /three} > + @autoload.expects(:gemsearchpaths).returns %w{/four /four} > FileTest.expects(:directory?).with("/one/loaddir").returns true > FileTest.expects(:directory?).with("/two/loaddir").returns false > FileTest.expects(:directory?).with("/three/loaddir").returns true > - @autoload.searchpath.should == ["/one/loaddir", "/three/loaddir"] > + FileTest.expects(:directory?).with("/four/loaddir").returns true > + @autoload.searchpath.should == ["/four/loaddir", "/one/loaddir", > "/three/loaddir"] > end > end > > -- > 1.7.1 >
-- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to puppet-dev@googlegroups.com. To unsubscribe from this group, send email to puppet-dev+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.