diff options
author | Steve Baker <sbaker@redhat.com> | 2016-08-13 15:23:08 +1200 |
---|---|---|
committer | Steve Baker <sbaker@redhat.com> | 2016-08-16 01:32:44 +0000 |
commit | bc3b84fb609985511510aff2aee62dbf05268b81 (patch) | |
tree | b08b5a31bfc04b442e472f4c7a4cfcc4aada2f02 /heat/objects | |
parent | 3ab0ede98c6dc0c0327977be994c139113fc0489 (diff) | |
download | heat-bc3b84fb609985511510aff2aee62dbf05268b81.tar.gz |
A context cache for Resource objects
A context cache which memoizes the resources fetched by calls to
Resource.get_all_by_root_stack(..., cache=True)
which are recalled by subsequent calls to Resource.get_all_by_stack.
Because get_all_by_stack returns a collection instead of a single
resource, there is no way of taking advantage of the SQLAlchemy
identity map [1].
[1] http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#is-the-session-a-cache
Change-Id: Ia5aae0c86a586041020e9798566c9e0af48c180d
Partial-Bug: #1578854
Diffstat (limited to 'heat/objects')
-rw-r--r-- | heat/objects/resource.py | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/heat/objects/resource.py b/heat/objects/resource.py index 968781224..69cfd5177 100644 --- a/heat/objects/resource.py +++ b/heat/objects/resource.py @@ -15,6 +15,8 @@ """Resource object.""" +import collections + from oslo_config import cfg from oslo_serialization import jsonutils from oslo_versionedobjects import base @@ -42,6 +44,19 @@ def retry_on_conflict(func): return wrapper(func) +class ResourceCache(object): + + def __init__(self): + self.delete_all() + + def delete_all(self): + self.by_stack_id_name = collections.defaultdict(dict) + + def set_by_stack_id(self, resources): + for res in six.itervalues(resources): + self.by_stack_id_name[res.stack_id][res.name] = res + + class Resource( heat_base.HeatObject, base.VersionedObjectDictCompat, @@ -136,6 +151,10 @@ class Resource( @classmethod def get_all_by_stack(cls, context, stack_id, filters=None): + cache = context.cache(ResourceCache) + resources = cache.by_stack_id_name.get(stack_id) + if resources: + return dict(resources) resources_db = db_api.resource_get_all_by_stack(context, stack_id, filters) return cls._resources_to_dict(context, resources_db) @@ -165,12 +184,15 @@ class Resource( return dict(resources) @classmethod - def get_all_by_root_stack(cls, context, stack_id, filters): + def get_all_by_root_stack(cls, context, stack_id, filters, cache=False): resources_db = db_api.resource_get_all_by_root_stack( context, stack_id, filters) - return cls._resources_to_dict(context, resources_db) + all = cls._resources_to_dict(context, resources_db) + if cache: + context.cache(ResourceCache).set_by_stack_id(all) + return all @classmethod def purge_deleted(cls, context, stack_id): |