diff options
author | Thomas Herve <therve@redhat.com> | 2016-09-26 17:17:14 +0200 |
---|---|---|
committer | Thomas Herve <therve@redhat.com> | 2016-09-30 21:33:29 +0200 |
commit | 11223da9aceab449076ccbeee1e08389cda44232 (patch) | |
tree | b8caf3765b43fb13bac58646188f27cabcb81bd0 /heat/engine | |
parent | dd707bc997715365dc76a3decea7b4f8d658375f (diff) | |
download | heat-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.py | 16 | ||||
-rw-r--r-- | heat/engine/resources/stack_resource.py | 3 | ||||
-rw-r--r-- | heat/engine/resources/template_resource.py | 8 |
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. |