diff options
author | Steven Danna <steve@opscode.com> | 2013-07-23 17:34:25 -0700 |
---|---|---|
committer | Steven Danna <steve@opscode.com> | 2013-07-23 17:34:25 -0700 |
commit | 3fac9809cfec637b817f5891bcc7a1dbdf8d62f0 (patch) | |
tree | e2410eabb960408848d7dab123104e64c52470c0 | |
parent | f894fa96fd2cb64cf260d83783ba75545e307ec3 (diff) | |
download | chef-3fac9809cfec637b817f5891bcc7a1dbdf8d62f0.tar.gz |
Avoid using define_method to stop memory leak.
Analysis of Ruby's ObjectSpace found that simply loading LWRPs were
creating ResourceCollections and other objects that were not being
garbage collected. Bisecting the code identified the define_method on
initialize as the culprit.
This patch repalces the define_method with a class_eval of a string.
It isn't pretty but it appears to resolve the known test cases for
this memory leak.
-rw-r--r-- | chef/lib/chef/resource.rb | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/chef/lib/chef/resource.rb b/chef/lib/chef/resource.rb index 576b2e699b..7f99f259fe 100644 --- a/chef/lib/chef/resource.rb +++ b/chef/lib/chef/resource.rb @@ -789,16 +789,18 @@ F # create a new constructor that wraps the old one and adds the actions # specified in the DSL - old_init = instance_method(:initialize) + alias_method :old_init, :initialize - define_method(:initialize) do |name, *optional_args| - args_run_context = optional_args.shift - @resource_name = rname.to_sym - old_init.bind(self).call(name, args_run_context) + new_init =<<INIT + def initialize(name, run_context=nil) + @resource_name = "#{rname}".to_sym + old_init(name, run_context) @action = self.class.action_to_set_default || @action allowed_actions.push(self.class.actions_to_create).flatten! - end - end + end +INIT + class_eval(new_init) + end # register new class as a Chef::Resource class_name = convert_to_class_name(rname) |