summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG9
-rw-r--r--lib/puppet/parser/parser_support.rb21
-rwxr-xr-xtest/language/parser.rb1
3 files changed, 22 insertions, 9 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 80152a2d1..659ae28b7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,12 @@
+ Found an array that leaked pretty quickly between reparsing
+ files, thanks to work by Adam Jacob and Arjuna Christenson
+ (the finding, not the leak). I'm going to act like this
+ fixes #1131, at least for now, but I doubt it does,
+ since that shows general memory growth over time, whereas
+ the leak here should go away as soon as files are reparsed
+ (because the parser is holding the reference to the leaking
+ array).
+
Fixed #1147: Cached nodes are correctly considered out of
date if the node facts have been updated (thus causing
node facts to again be available in manifests, for those
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index ccfc4d48a..b86a4792b 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -123,13 +123,17 @@ class Puppet::Parser::Parser
def fqfind(namespace, name, table)
namespace = namespace.downcase
name = name.to_s.downcase
+
+ # If our classname is fully qualified or we have no namespace,
+ # just try directly for the class, and return either way.
if name =~ /^::/ or namespace == ""
classname = name.sub(/^::/, '')
- unless table[classname]
- self.load(classname)
- end
+ self.load(classname) unless table[classname]
return table[classname]
end
+
+ # Else, build our namespace up piece by piece, checking
+ # for the class in each namespace.
ary = namespace.split("::")
while ary.length > 0
@@ -221,7 +225,6 @@ class Puppet::Parser::Parser
return false if classname == ""
filename = classname.gsub("::", File::SEPARATOR)
- loaded = false
# First try to load the top-level module
mod = filename.scan(/^[\w-]+/).shift
unless @loaded.include?(mod)
@@ -229,24 +232,24 @@ class Puppet::Parser::Parser
begin
import(mod)
Puppet.info "Autoloaded module %s" % mod
- loaded = true
rescue Puppet::ImportError => detail
# We couldn't load the module
end
end
- unless filename == mod and ! @loaded.include?(mod)
- @loaded << mod
+ return true if classes.include?(classname)
+
+ unless @loaded.include?(filename)
+ @loaded << filename
# Then the individual file
begin
import(filename)
Puppet.info "Autoloaded file %s from module %s" % [filename, mod]
- loaded = true
rescue Puppet::ImportError => detail
# We couldn't load the file
end
end
- return loaded
+ return classes.include?(classname)
end
# Split an fq name into a namespace and name
diff --git a/test/language/parser.rb b/test/language/parser.rb
index 2a0e9c02d..2161a33f5 100755
--- a/test/language/parser.rb
+++ b/test/language/parser.rb
@@ -1141,6 +1141,7 @@ file { "/tmp/yayness":
name = "sub"
mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
+ Puppet.err :yay
# First try it with a namespace
klass = parser.findclass("separate", name)
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with a namespace")