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

Change-Id: Ibf80e95e69a2f27ed29754a2e0f1125e8eed0775
Closes-Bug: #1454873
Zane Bitter 8 years ago
parent f81cb5dbd1
commit 60300b0149
  1. 13
  2. 11

@ -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
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.

@ -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
def stack(self):
stack = self._stackref()
assert stack is not None, "Need a reference to the Stack object"
return stack
def stack(self, stack):
self._stackref = weakref.ref(stack)
def reparse(self): =,