Break reference cycle between Environment and ResourceRegistry

The commit 08431c7c06 added a reference to
the Environment object from the ResourceRegistry object, which is itself
an attribute of the environment. This causes a reference cycle that
means that the environment and everything referenced by it (including
the potentially very large files dict) will only be deallocated when it
is garbage collected since the reference counts will never hit zero.
This has probably been contributing substantially to memory
fragmentation.

Change-Id: Ib251b5f5ffc07fe1a06f5e44124024831d4ba1b2
Partial-Bug: #1570974
This commit is contained in:
Zane Bitter 2016-04-20 14:41:40 -04:00
parent 3f26de868b
commit ec5e5c57a2
2 changed files with 10 additions and 9 deletions

View File

@ -192,9 +192,10 @@ class TemplateResourceInfo(ResourceInfo):
data = template_resource.TemplateResource.get_template_file(
self.template_name,
allowed_schemes)
env = self.registry.environment
param_defaults = self.registry.param_defaults
return template_resource.generate_class_from_template(str(self.name),
data, env)
data,
param_defaults)
def get_class_to_instantiate(self):
from heat.engine.resources import template_resource
@ -248,10 +249,10 @@ class GlobResourceInfo(MapResourceInfo):
class ResourceRegistry(object):
"""By looking at the environment, find the resource implementation."""
def __init__(self, global_registry, env):
def __init__(self, global_registry, param_defaults):
self._registry = {'resources': {}}
self.global_registry = global_registry
self.environment = env
self.param_defaults = param_defaults
def load(self, json_snippet):
self._load_registry([], json_snippet)
@ -654,11 +655,11 @@ class Environment(object):
global_registry = None
event_sink_classes = {}
self.registry = ResourceRegistry(global_registry, self)
self.registry.load(env.get(env_fmt.RESOURCE_REGISTRY, {}))
self.param_defaults = env.get(env_fmt.PARAMETER_DEFAULTS, {})
self.registry = ResourceRegistry(global_registry, self.param_defaults)
self.registry.load(env.get(env_fmt.RESOURCE_REGISTRY, {}))
self.encrypted_param_names = env.get(env_fmt.ENCRYPTED_PARAM_NAMES, [])
if env_fmt.PARAMETERS in env:

View File

@ -31,9 +31,9 @@ REMOTE_SCHEMES = ('http', 'https')
LOCAL_SCHEMES = ('file',)
def generate_class_from_template(name, data, env):
def generate_class_from_template(name, data, param_defaults):
tmpl = template.Template(template_format.parse(data))
props, attrs = TemplateResource.get_schemas(tmpl, env.param_defaults)
props, attrs = TemplateResource.get_schemas(tmpl, param_defaults)
cls = type(name, (TemplateResource,),
{'properties_schema': props,
'attributes_schema': attrs})