summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <454857+lamont-granquist@users.noreply.github.com>2022-03-30 17:54:33 -0700
committerGitHub <noreply@github.com>2022-03-30 17:54:33 -0700
commitb85e8b81b5a0a8c63cc46b695a2b1343df5e5ea4 (patch)
tree80f791dcb804e8a500d4cab9101973b950c4af0e
parent0cf5fa140eca24f8c738200aaae5e9123123663a (diff)
parent3b6a58fc15081c49d5ce324394027685a0b16af8 (diff)
downloadchef-b85e8b81b5a0a8c63cc46b695a2b1343df5e5ea4.tar.gz
Merge pull request #12743 from chef/lcg/fix-attribute-performance-issues2
-rw-r--r--chef-utils/lib/chef-utils/mash.rb8
-rw-r--r--lib/chef/node/attribute.rb23
-rw-r--r--lib/chef/node/mixin/deep_merge_cache.rb8
3 files changed, 32 insertions, 7 deletions
diff --git a/chef-utils/lib/chef-utils/mash.rb b/chef-utils/lib/chef-utils/mash.rb
index bb48064aa3..14159d175a 100644
--- a/chef-utils/lib/chef-utils/mash.rb
+++ b/chef-utils/lib/chef-utils/mash.rb
@@ -106,6 +106,14 @@ module ChefUtils
alias_method :regular_update, :update
end
+ unless method_defined?(:regular_clear)
+ alias_method :regular_clear, :clear
+ end
+
+ unless method_defined?(:regular_delete)
+ alias_method :regular_delete, :delete
+ end
+
# @param key<Object> The key to get.
def [](key)
regular_reader(key)
diff --git a/lib/chef/node/attribute.rb b/lib/chef/node/attribute.rb
index 6a8e72004b..d235ce4faa 100644
--- a/lib/chef/node/attribute.rb
+++ b/lib/chef/node/attribute.rb
@@ -452,17 +452,34 @@ class Chef
# method-style access to attributes (has to come after the prepended ImmutablizeHash)
def read(*path)
- merged_attributes.read(*path)
+ if path[0].nil?
+ Chef::Log.warn "Calling node.read() without any path argument is very slow, probably a bug, and should be avoided"
+ merged_attributes.read(*path) # re-merges everything, slow edge case
+ else
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
+ deep_merge_cache.read(*path)
+ end
end
alias :dig :read
def read!(*path)
- merged_attributes.read!(*path)
+ if path[0].nil?
+ Chef::Log.warn "Calling node.read!() without any path argument is very slow, probably a bug, and should be avoided"
+ merged_attributes.read!(*path) # re-merges everything, slow edge case
+ else
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
+ deep_merge_cache.read!(*path)
+ end
end
def exist?(*path)
- merged_attributes.exist?(*path)
+ if path[0].nil?
+ true
+ else
+ self[path[0]] unless path[0].nil? # force deep_merge_cache key construction if necessary
+ deep_merge_cache.exist?(*path)
+ end
end
def write(level, *args, &block)
diff --git a/lib/chef/node/mixin/deep_merge_cache.rb b/lib/chef/node/mixin/deep_merge_cache.rb
index 8978d77ea0..be16197850 100644
--- a/lib/chef/node/mixin/deep_merge_cache.rb
+++ b/lib/chef/node/mixin/deep_merge_cache.rb
@@ -30,7 +30,7 @@ class Chef
@merged_attributes = nil
@combined_override = nil
@combined_default = nil
- @deep_merge_cache = {}
+ @deep_merge_cache = Chef::Node::ImmutableMash.new
end
# Invalidate a key in the deep_merge_cache. If called with nil, or no arg, this will invalidate
@@ -39,9 +39,9 @@ class Chef
# must invalidate the entire cache and re-deep-merge the entire node object.
def reset_cache(path = nil)
if path.nil?
- deep_merge_cache.clear
+ deep_merge_cache.regular_clear
else
- deep_merge_cache.delete(path.to_s)
+ deep_merge_cache.regular_delete(path.to_s)
end
end
@@ -53,7 +53,7 @@ class Chef
deep_merge_cache[key.to_s]
else
# save all the work of computing node[key]
- deep_merge_cache[key.to_s] = merged_attributes(key)
+ deep_merge_cache.internal_set(key.to_s, merged_attributes(key))
end
ret = ret.call while ret.is_a?(::Chef::DelayedEvaluator)
ret