summaryrefslogtreecommitdiff
path: root/heat/engine
diff options
context:
space:
mode:
authorThomas Herve <therve@redhat.com>2016-09-26 17:17:14 +0200
committerThomas Herve <therve@redhat.com>2016-09-30 21:33:29 +0200
commit11223da9aceab449076ccbeee1e08389cda44232 (patch)
treeb8caf3765b43fb13bac58646188f27cabcb81bd0 /heat/engine
parentdd707bc997715365dc76a3decea7b4f8d658375f (diff)
downloadheat-11223da9aceab449076ccbeee1e08389cda44232.tar.gz
Break cycle between Resource and Attributes
Attributes hold a reference to Resource via the attribute resolution method. Let's add a weakref here to break the cycle. Change-Id: I1cd22476c7d2d9ca0a090947b8f28d8afc413fc7 (cherry picked from commit c3021de31c23d70fb1d766f4ac3c521ad7ede7d5)
Diffstat (limited to 'heat/engine')
-rw-r--r--heat/engine/resource.py16
-rw-r--r--heat/engine/resources/stack_resource.py3
-rw-r--r--heat/engine/resources/template_resource.py8
3 files changed, 22 insertions, 5 deletions
diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 2946c60d7..872beb4fb 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -209,7 +209,7 @@ class Resource(object):
"""
return attributes.Attributes(self.name,
self.attributes_schema,
- self._resolve_all_attributes)
+ self._make_resolver(weakref.ref(self)))
def __init__(self, name, definition, stack):
@@ -2269,3 +2269,17 @@ class Resource(object):
except Exception:
return False
return True
+
+ @staticmethod
+ def _make_resolver(ref):
+ """Return an attribute resolution method.
+
+ This builds a resolver without a strong reference to this resource, to
+ break a possible cycle.
+ """
+ def resolve(attr):
+ res = ref()
+ if res is None:
+ raise RuntimeError("Resource collected")
+ return res._resolve_all_attributes(attr)
+ return resolve
diff --git a/heat/engine/resources/stack_resource.py b/heat/engine/resources/stack_resource.py
index 2978879a9..e0278e8fe 100644
--- a/heat/engine/resources/stack_resource.py
+++ b/heat/engine/resources/stack_resource.py
@@ -13,6 +13,7 @@
import json
import warnings
+import weakref
from oslo_config import cfg
from oslo_log import log as logging
@@ -87,7 +88,7 @@ class StackResource(resource.Resource):
# with all available outputs
self.attributes = attributes.Attributes(
self.name, self.attributes_schema,
- self._resolve_all_attributes)
+ self._make_resolver(weakref.ref(self)))
def _needs_update(self, after, before, after_props, before_props,
prev_resource, check_init_complete=True):
diff --git a/heat/engine/resources/template_resource.py b/heat/engine/resources/template_resource.py
index 116b5731b..02c8306c5 100644
--- a/heat/engine/resources/template_resource.py
+++ b/heat/engine/resources/template_resource.py
@@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import weakref
+
from oslo_serialization import jsonutils
from requests import exceptions
import six
@@ -118,9 +120,9 @@ class TemplateResource(stack_resource.StackResource):
tmpl, self.stack.env.param_defaults)
self.attributes_schema.update(self.base_attributes_schema)
- self.attributes = attributes.Attributes(self.name,
- self.attributes_schema,
- self._resolve_all_attributes)
+ self.attributes = attributes.Attributes(
+ self.name, self.attributes_schema,
+ self._make_resolver(weakref.ref(self)))
def child_params(self):
"""Override method of child_params for the resource.