Get rid of circular references in Resource and Function

Circular references cause practically every bit of data that Heat uses to
remain in memory until the completion of an operation, and even then to
only be freed once the loop is detected by the garbage collector. By
breaking all of the loops using weak references, we can ensure that things
will get freed when they are no longer referenced without the need to wait
for garbage collection (which should also take a lot less time). This
change removes the loops from Resource and Function objects back to the
Stack.

Change-Id: Ibf80e95e69a2f27ed29754a2e0f1125e8eed0775
Closes-Bug: #1454873
This commit is contained in:
Zane Bitter 2015-05-15 17:18:12 -04:00
parent f81cb5dbd1
commit 60300b0149
2 changed files with 23 additions and 1 deletions

View File

@ -14,6 +14,7 @@
import abc
import collections
import itertools
import weakref
import six
@ -33,10 +34,20 @@ class Function(object):
{ <fn_name> : <args> }
"""
super(Function, self).__init__()
self.stack = stack
self._stackref = weakref.ref(stack) if stack is not None else None
self.fn_name = fn_name
self.args = args
@property
def stack(self):
ref = self._stackref
if ref is None:
return None
stack = ref()
assert stack is not None, "Need a reference to the Stack object"
return stack
def validate(self):
"""
Validate arguments without resolving the function.

View File

@ -15,6 +15,7 @@ import base64
import contextlib
import datetime as dt
import warnings
import weakref
from oslo_config import cfg
from oslo_log import log as logging
@ -218,6 +219,16 @@ class Resource(object):
self.replaced_by = resource.replaced_by
self.current_template_id = resource.current_template_id
@property
def stack(self):
stack = self._stackref()
assert stack is not None, "Need a reference to the Stack object"
return stack
@stack.setter
def stack(self, stack):
self._stackref = weakref.ref(stack)
def reparse(self):
self.properties = self.t.properties(self.properties_schema,
self.context)