Do not query database for every metadata_get
This change stores the rsrc_metadata locally when the Resource object is created so that the database is not queried every time metadata_get is called. There are some instances where the metadata must come from the database (eg, polling for waitcondition signal) so an optional refresh arg is added to metadata_get to force a database refresh of the stored rsrc_metadata. This results in one less sql query for every time metadata_get is called, which will help the optimising effort for Related-Bug: #1306743 Change-Id: Iad2d810c299347ae3b6a4a8329bbd314ee4b5c16
This commit is contained in:
parent
96791aaa10
commit
65c6c3bac8
|
@ -141,6 +141,7 @@ class Resource(object):
|
|||
self._data = db_api.resource_data_get_all(self, resource.data)
|
||||
except exception.NotFound:
|
||||
self._data = {}
|
||||
self._rsrc_metadata = resource.rsrc_metadata
|
||||
self.created_time = resource.created_at
|
||||
self.updated_time = resource.updated_at
|
||||
else:
|
||||
|
@ -154,6 +155,7 @@ class Resource(object):
|
|||
self.status_reason = ''
|
||||
self.id = None
|
||||
self._data = {}
|
||||
self._rsrc_metadata = None
|
||||
self.created_time = None
|
||||
self.updated_time = None
|
||||
|
||||
|
@ -181,11 +183,16 @@ class Resource(object):
|
|||
return result
|
||||
return not result
|
||||
|
||||
def metadata_get(self):
|
||||
def metadata_get(self, refresh=False):
|
||||
if refresh:
|
||||
self._rsrc_metadata = None
|
||||
if self.id is None:
|
||||
return self.parsed_template('Metadata')
|
||||
if self._rsrc_metadata is not None:
|
||||
return self._rsrc_metadata
|
||||
rs = db_api.resource_get(self.stack.context, self.id)
|
||||
rs.refresh(attrs=['rsrc_metadata'])
|
||||
self._rsrc_metadata = rs.rsrc_metadata
|
||||
return rs.rsrc_metadata
|
||||
|
||||
def metadata_set(self, metadata):
|
||||
|
@ -193,6 +200,7 @@ class Resource(object):
|
|||
raise exception.ResourceNotAvailable(resource_name=self.name)
|
||||
rs = db_api.resource_get(self.stack.context, self.id)
|
||||
rs.update_and_save({'rsrc_metadata': metadata})
|
||||
self._rsrc_metadata = metadata
|
||||
|
||||
def type(self):
|
||||
return self.t['Type']
|
||||
|
@ -444,7 +452,7 @@ class Resource(object):
|
|||
'type': self.type(),
|
||||
'action': self.action,
|
||||
'status': self.status,
|
||||
'metadata': self.metadata_get(),
|
||||
'metadata': self.metadata_get(refresh=True),
|
||||
'resource_data': self.data()
|
||||
}
|
||||
|
||||
|
@ -736,6 +744,7 @@ class Resource(object):
|
|||
new_rs = db_api.resource_create(self.context, rs)
|
||||
self.id = new_rs.id
|
||||
self.created_time = new_rs.created_at
|
||||
self._rsrc_metadata = metadata
|
||||
except Exception as ex:
|
||||
logger.error(_('DB error %s') % ex)
|
||||
|
||||
|
|
|
@ -427,11 +427,11 @@ class Server(stack_user.StackUser):
|
|||
else:
|
||||
self.data_set('password', password, True)
|
||||
|
||||
def metadata_get(self):
|
||||
def metadata_get(self, refresh=False):
|
||||
if self.user_data_software_config():
|
||||
return self._build_deployments_metadata()
|
||||
else:
|
||||
return super(Server, self).metadata_get()
|
||||
return super(Server, self).metadata_get(refresh)
|
||||
|
||||
def metadata_set(self, metadata):
|
||||
if not self.user_data_software_config():
|
||||
|
|
|
@ -72,7 +72,7 @@ class WaitConditionHandle(signal_responder.SignalResponder):
|
|||
return
|
||||
|
||||
if self._metadata_format_ok(new_metadata):
|
||||
rsrc_metadata = self.metadata_get()
|
||||
rsrc_metadata = self.metadata_get(refresh=True)
|
||||
if new_metadata['UniqueId'] in rsrc_metadata:
|
||||
logger.warning(_("Overwriting Metadata item for UniqueId %s!")
|
||||
% new_metadata['UniqueId'])
|
||||
|
@ -89,14 +89,14 @@ class WaitConditionHandle(signal_responder.SignalResponder):
|
|||
'''
|
||||
Return a list of the Status values for the handle signals
|
||||
'''
|
||||
return [v['Status'] for v in self.metadata_get().values()]
|
||||
return [v['Status'] for v in self.metadata_get(refresh=True).values()]
|
||||
|
||||
def get_status_reason(self, status):
|
||||
'''
|
||||
Return a list of reasons associated with a particular status
|
||||
'''
|
||||
return [v['Reason']
|
||||
for v in self.metadata_get().values()
|
||||
for v in self.metadata_get(refresh=True).values()
|
||||
if v['Status'] == status]
|
||||
|
||||
|
||||
|
@ -274,7 +274,7 @@ class WaitCondition(resource.Resource):
|
|||
handle_res_name = self._get_handle_resource_name()
|
||||
handle = self.stack[handle_res_name]
|
||||
if key == 'Data':
|
||||
meta = handle.metadata_get()
|
||||
meta = handle.metadata_get(refresh=True)
|
||||
# Note, can't use a dict generator on python 2.6, hence:
|
||||
res = dict([(k, meta[k]['Data']) for k in meta])
|
||||
logger.debug(_('%(name)s.GetAtt(%(key)s) == %(res)s') %
|
||||
|
|
|
@ -290,7 +290,9 @@ class WaitCondMetadataUpdateTest(HeatTestCase):
|
|||
update_metadata('456', 'blarg', 'wibble')
|
||||
self.assertEqual('{"123": "foo", "456": "blarg"}',
|
||||
watch.FnGetAtt('Data'))
|
||||
self.assertEqual('{"123": "foo", "456": "blarg"}',
|
||||
self.assertEqual('{"123": "foo"}',
|
||||
inst.metadata_get()['test'])
|
||||
self.assertEqual('{"123": "foo", "456": "blarg"}',
|
||||
inst.metadata_get(refresh=True)['test'])
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
|
Loading…
Reference in New Issue