diff options
author | Lamont Granquist <454857+lamont-granquist@users.noreply.github.com> | 2022-03-30 16:46:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-30 16:46:28 -0700 |
commit | eff066b4053e4878925c4af0f8d8410ece5bd339 (patch) | |
tree | 312ebf33e23e2d3edc6bb05b01941c386d29f5ad | |
parent | b2fd957715ea490d49f7b27daa5101ecf0a23c4b (diff) | |
parent | cdeedccf715afe1d4361245a2a3194d8ca82ca09 (diff) | |
download | chef-eff066b4053e4878925c4af0f8d8410ece5bd339.tar.gz |
Merge pull request #12742 from chef/lcg/fix-attribute-performance-issues
-rw-r--r-- | chef-utils/lib/chef-utils/mash.rb | 8 | ||||
-rw-r--r-- | lib/chef/node/attribute.rb | 23 | ||||
-rw-r--r-- | lib/chef/node/mixin/deep_merge_cache.rb | 8 |
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 |