summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-12-09 11:17:15 -0800
committerLamont Granquist <lamont@scriptkiddie.org>2015-12-14 13:27:00 -0800
commiteff4d262ae2f464152bcf931322e427773216a13 (patch)
treed72a38882c876d8a8afa0edae1bee46119e3676c
parent491e99e796673b5a3762d5a47ed51fabf1b6f8f1 (diff)
downloadchef-eff4d262ae2f464152bcf931322e427773216a13.tar.gz
rubygems performance tweak
-rw-r--r--chef-config/lib/chef-config/config.rb5
-rw-r--r--lib/chef/provider/package/rubygems.rb35
2 files changed, 27 insertions, 13 deletions
diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb
index d8cc4bff37..320e63b9dd 100644
--- a/chef-config/lib/chef-config/config.rb
+++ b/chef-config/lib/chef-config/config.rb
@@ -686,6 +686,11 @@ module ChefConfig
default :normal_attribute_whitelist, nil
default :override_attribute_whitelist, nil
+ # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
+ # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
+ # round trips.
+ default :rubygems_cache_enabled, true
+
config_context :windows_service do
# Set `watchdog_timeout` to the number of seconds to wait for a chef-client run
# to finish
diff --git a/lib/chef/provider/package/rubygems.rb b/lib/chef/provider/package/rubygems.rb
index 729f755b2a..a608b90458 100644
--- a/lib/chef/provider/package/rubygems.rb
+++ b/lib/chef/provider/package/rubygems.rb
@@ -159,19 +159,28 @@ class Chef
# Find the newest gem version available from Gem.sources that satisfies
# the constraints of +gem_dependency+
def find_newest_remote_version(gem_dependency, *sources)
- available_gems = dependency_installer.find_gems_with_sources(gem_dependency)
- spec, source = if available_gems.respond_to?(:last)
- # DependencyInstaller sorts the results such that the last one is
- # always the one it considers best.
- spec_with_source = available_gems.last
- spec_with_source && spec_with_source
- else
- # Rubygems 2.0 returns a Gem::Available set, which is a
- # collection of AvailableSet::Tuple structs
- available_gems.pick_best!
- best_gem = available_gems.set.first
- best_gem && [best_gem.spec, best_gem.source]
- end
+ spec, source =
+ if !Chef::Config[:rubygems_cache_enabled]
+ # Use the API that 'gem install' calls which does not pull down the rubygems universe
+ rs = Gem::RequestSet.new
+ rs.import [ gem_dependency ]
+ # This returns the gem which satisfies the dependency along with all of its deps
+ resolved_spec = rs.resolve.select { |spec| spec.name == gem_dependency.name }.first.spec
+ resolved_spec && resolved_spec
+ else
+ available_gems = dependency_installer.find_gems_with_sources(gem_dependency)
+ if available_gems.respond_to?(:last)
+ # Rubygems < 2.0 sorts results such that the last one is the 'best' one
+ spec_with_source = available_gems.last
+ spec_with_source && spec_with_source
+ else
+ # Rubygems 2.0 returns a Gem::Available set, which is a
+ # collection of AvailableSet::Tuple structs
+ available_gems.pick_best!
+ best_gem = available_gems.set.first
+ best_gem && [best_gem.spec, best_gem.source]
+ end
+ end
version = spec && spec.version
if version