summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-06-06 10:50:02 -0700
committerJohn Keiser <john@johnkeiser.com>2015-06-08 08:44:39 -0700
commit8d4e9d44995d6f7de5a0b681616ed8241e39ece3 (patch)
treed23d7be8cbd127f0557b68e3487d994a000c3f98
parenta6aa7b65b54173324c93f5f3f73c66c724ca963e (diff)
downloadchef-8d4e9d44995d6f7de5a0b681616ed8241e39ece3.tar.gz
Improve performance of method_missingjk/perf
by not repeatedly sorting and calling enabled_handlers (This was causing major slowdown in tests)
-rw-r--r--lib/chef/resource.rb20
-rw-r--r--lib/chef/resource_resolver.rb29
2 files changed, 35 insertions, 14 deletions
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index ab955f5454..d74b942e7d 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -1088,10 +1088,30 @@ class Chef
# NOTE: that we do not support unregistering classes as descendents like
# we used to for LWRP unloading because that was horrible and removed in
# Chef-12.
+ # @deprecated
+ # @api private
alias :resource_classes :descendants
+ # @deprecated
+ # @api private
alias :find_subclass_by_name :find_descendants_by_name
end
+ # @deprecated
+ # @api private
+ # We memoize a sorted version of descendants so that resource lookups don't
+ # have to sort all the things, all the time.
+ # This was causing performance issues in test runs, and probably in real
+ # life as well.
+ @@sorted_descendants = nil
+ def self.sorted_descendants
+ @@sorted_descendants ||= descendants.sort_by { |x| x.to_s }
+ end
+ def self.inherited(other)
+ super
+ @@sorted_descendants = nil
+ end
+
+
# If an unknown method is invoked, determine whether the enclosing Provider's
# lexical scope can fulfill the request. E.g. This happens when the Resource's
# block invokes new_resource.
diff --git a/lib/chef/resource_resolver.rb b/lib/chef/resource_resolver.rb
index 1bd8892239..1eb5e6d840 100644
--- a/lib/chef/resource_resolver.rb
+++ b/lib/chef/resource_resolver.rb
@@ -79,35 +79,36 @@ class Chef
end
def prioritized_handlers
- @prioritized_handlers ||=
- priority_map.list_handlers(node, resource)
+ @prioritized_handlers ||= priority_map.list_handlers(node, resource)
end
module Deprecated
# return a deterministically sorted list of Chef::Resource subclasses
+ # @deprecated Now prioritized_handlers does its own work (more efficiently)
def resources
- @resources ||= Chef::Resource.descendants
+ Chef::Resource.sorted_descendants
end
- # this cut looks at if the resource can handle the resource type on the node
+ # A list of all handlers
+ # @deprecated Now prioritized_handlers does its own work
def enabled_handlers
- @enabled_handlers ||=
- resources.select do |klass|
- klass.provides?(node, resource)
- end.sort {|a,b| a.to_s <=> b.to_s }
+ resources.select { |klass| klass.provides?(node, resource) }
end
protected
# If there are no providers for a DSL, we search through the
def prioritized_handlers
- @prioritized_handlers ||= super || begin
- if !enabled_handlers.empty?
- Chef::Log.deprecation("#{resource} is marked as providing DSL #{resource}, but provides #{resource.inspect} was never called!")
- Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.")
+ @prioritized_handlers ||= super ||
+ resources.select do |klass|
+ # Don't bother calling provides? unless it's overriden. We already
+ # know prioritized_handlers
+ if klass.method(:provides?).owner != Chef::Resource && klass.provides?(node, resource)
+ Chef::Log.deprecation("Resources #{provided.join(", ")} are marked as providing DSL #{resource}, but provides #{resource.inspect} was never called!")
+ Chef::Log.deprecation("In Chef 13, this will break: you must call provides to mark the names you provide, even if you also override provides? yourself.")
+ true
+ end
end
- enabled_handlers
- end
end
end
prepend Deprecated