Eager-load properties for nested resource list

When doing "openstack stack resource list --nested-depth=n", we were
lazy-loading the resources' properties data. This is expensive, especially
when there are a large number of resources. Eager-load the data, as we
always use it to show the resources.

For consistency, always eager-load the resource 'data' (even in
resource_get), because the Resource versioned object accesses it
unconditionally.

Change-Id: Idb871fddf77bf24828878c315e19e200c28841be
Related-Bug: #1665503
changes/43/521643/1
Zane Bitter 5 years ago
parent 38f1975cf7
commit dbc852b47a
  1. 10
      heat/db/sqlalchemy/api.py
  2. 2
      heat/engine/service.py
  3. 2
      heat/objects/event.py
  4. 8
      heat/objects/resource.py

@ -178,9 +178,9 @@ def raw_template_files_get(context, files_id):
def resource_get(context, resource_id, refresh=False, refresh_data=False,
eager=True):
query = context.session.query(models.Resource)
query = query.options(orm.joinedload("data"))
if eager:
query = query.options(orm.joinedload("data")).options(
orm.joinedload("rsrc_prop_data"))
query = query.options(orm.joinedload("rsrc_prop_data"))
result = query.get(resource_id)
if not result:
@ -495,13 +495,17 @@ def resource_get_all_active_by_stack(context, stack_id):
return dict((res.id, res) for res in results)
def resource_get_all_by_root_stack(context, stack_id, filters=None):
def resource_get_all_by_root_stack(context, stack_id, filters=None,
eager=True):
query = context.session.query(
models.Resource
).filter_by(
root_stack_id=stack_id
).options(orm.joinedload("data"))
if eager:
query = query.options(orm.joinedload("rsrc_prop_data"))
query = db_filters.exact_filter(query, models.Resource, filters)
results = query.all()

@ -1746,7 +1746,7 @@ class EngineService(service.ServiceBase):
root_stack_identifier = st.identifier()
# find all resources associated with a root stack
all_r = resource_objects.Resource.get_all_by_root_stack(
cnxt, st.id, None)
cnxt, st.id, None, eager=False)
# find stacks to the requested nested_depth
stack_ids = {r.stack_id for r in six.itervalues(all_r)}

@ -79,7 +79,7 @@ class Event(
@property
def resource_properties(self):
if self._resource_properties is None:
LOG.info('rsrp_prop_data lazy load')
LOG.info('rsrc_prop_data lazy load')
rpd_obj = rpd.ResourcePropertiesData.get_by_id(
self._context, self.rsrc_prop_data_id)
self._resource_properties = rpd_obj.data or {}

@ -164,7 +164,7 @@ class Resource(
def properties_data(self):
if (not self._properties_data and
self.rsrc_prop_data_id is not None):
LOG.info('rsrp_prop_data lazy load')
LOG.info('rsrc_prop_data lazy load')
rpd_obj = rpd.ResourcePropertiesData.get_by_id(
self._context, self.rsrc_prop_data_id)
self._properties_data = rpd_obj.data or {}
@ -264,11 +264,13 @@ class Resource(
return dict(resources)
@classmethod
def get_all_by_root_stack(cls, context, stack_id, filters, cache=False):
def get_all_by_root_stack(cls, context, stack_id, filters, cache=False,
eager=True):
resources_db = db_api.resource_get_all_by_root_stack(
context,
stack_id,
filters)
filters,
eager=eager)
all = cls._resources_to_dict(context, resources_db)
if cache:
context.cache(ResourceCache).set_by_stack_id(all)

Loading…
Cancel
Save