Merge "Stop using needed_by field in resource"

This commit is contained in:
Zuul 2018-06-19 04:39:46 +00:00 committed by Gerrit Code Review
commit 2e8c262a30
4 changed files with 12 additions and 102 deletions

View File

@ -242,7 +242,6 @@ class Resource(status.ResourceStatus):
self.created_time = stack.created_time self.created_time = stack.created_time
self.updated_time = stack.updated_time self.updated_time = stack.updated_time
self._rpc_client = None self._rpc_client = None
self.needed_by = []
self.requires = set() self.requires = set()
self.replaces = None self.replaces = None
self.replaced_by = None self.replaced_by = None
@ -291,7 +290,6 @@ class Resource(status.ResourceStatus):
self._rsrc_prop_data_id = resource.rsrc_prop_data_id self._rsrc_prop_data_id = resource.rsrc_prop_data_id
self.created_time = resource.created_at self.created_time = resource.created_at
self.updated_time = resource.updated_at self.updated_time = resource.updated_at
self.needed_by = resource.needed_by
self.requires = set(resource.requires) self.requires = set(resource.requires)
self.replaces = resource.replaces self.replaces = resource.replaces
self.replaced_by = resource.replaced_by self.replaced_by = resource.replaced_by
@ -392,7 +390,7 @@ class Resource(status.ResourceStatus):
rs = {'stack_id': self.stack.id, rs = {'stack_id': self.stack.id,
'name': self.name, 'name': self.name,
'rsrc_prop_data_id': None, 'rsrc_prop_data_id': None,
'needed_by': self.needed_by, 'needed_by': [],
'requires': sorted(requires, reverse=True), 'requires': sorted(requires, reverse=True),
'replaces': self.id, 'replaces': self.id,
'action': self.INIT, 'action': self.INIT,
@ -529,15 +527,6 @@ class Resource(status.ResourceStatus):
""" """
pass pass
@classmethod
def set_needed_by(cls, db_rsrc, needed_by, expected_engine_id=None):
if db_rsrc:
db_rsrc.select_and_update(
{'needed_by': needed_by},
atomic_key=db_rsrc.atomic_key,
expected_engine_id=expected_engine_id
)
@classmethod @classmethod
def set_requires(cls, db_rsrc, requires): def set_requires(cls, db_rsrc, requires):
if db_rsrc: if db_rsrc:
@ -1887,8 +1876,8 @@ class Resource(status.ResourceStatus):
raise exception.StackValidationFailed(message=msg, path=path) raise exception.StackValidationFailed(message=msg, path=path)
def _update_replacement_data(self, template_id): def _update_replacement_data(self, template_id):
# Update the replacement resource's needed_by and replaces # Update the replacement resource's replaces field.
# fields. Make sure that the replacement belongs to the given # Make sure that the replacement belongs to the given
# template and there is no engine working on it. # template and there is no engine working on it.
if self.replaced_by is None: if self.replaced_by is None:
return return
@ -1899,19 +1888,16 @@ class Resource(status.ResourceStatus):
fields=('current_template_id', 'atomic_key')) fields=('current_template_id', 'atomic_key'))
except exception.NotFound: except exception.NotFound:
LOG.info("Could not find replacement of resource %(name)s " LOG.info("Could not find replacement of resource %(name)s "
"with id %(id)s while updating needed_by.", "with id %(id)s while updating replaces.",
{'name': self.name, 'id': self.replaced_by}) {'name': self.name, 'id': self.replaced_by})
return return
if (db_res.current_template_id == template_id): if (db_res.current_template_id == template_id):
# Following update failure is ignorable; another # Following update failure is ignorable; another
# update might have locked/updated the resource. # update might have locked/updated the resource.
if db_res.select_and_update( db_res.select_and_update({'replaces': None},
{'needed_by': self.needed_by, atomic_key=db_res.atomic_key,
'replaces': None}, expected_engine_id=None)
atomic_key=db_res.atomic_key,
expected_engine_id=None):
self._incr_atomic_key(self._atomic_key)
def delete_convergence(self, template_id, engine_id, timeout, def delete_convergence(self, template_id, engine_id, timeout,
progress_callback=None): progress_callback=None):
@ -1923,10 +1909,9 @@ class Resource(status.ResourceStatus):
Also, since this resource is visited as part of clean-up phase, Also, since this resource is visited as part of clean-up phase,
the needed_by should be updated. If this resource was the needed_by should be updated. If this resource was
replaced by more recent resource, then delete this and update replaced by more recent resource, then delete this and update
the replacement resource's needed_by and replaces fields. the replacement resource's replaces field.
""" """
self._calling_engine_id = engine_id self._calling_engine_id = engine_id
self.needed_by = []
if self.current_template_id != template_id: if self.current_template_id != template_id:
# just delete the resources in INIT state # just delete the resources in INIT state
@ -2073,7 +2058,7 @@ class Resource(status.ResourceStatus):
'name': self.name, 'name': self.name,
'rsrc_prop_data_id': 'rsrc_prop_data_id':
self._create_or_replace_rsrc_prop_data(), self._create_or_replace_rsrc_prop_data(),
'needed_by': self.needed_by, 'needed_by': [],
'requires': sorted(self.requires, reverse=True), 'requires': sorted(self.requires, reverse=True),
'replaces': self.replaces, 'replaces': self.replaces,
'replaced_by': self.replaced_by, 'replaced_by': self.replaced_by,

View File

@ -1444,31 +1444,15 @@ class Stack(collections.Mapping):
def _update_or_store_resources(self): def _update_or_store_resources(self):
self.ext_rsrcs_db = self.db_active_resources_get() self.ext_rsrcs_db = self.db_active_resources_get()
curr_name_translated_dep = self.dependencies.translate(lambda res:
res.name)
rsrcs = {} rsrcs = {}
def update_needed_by(res):
new_requirers = set(
rsrcs[rsrc_name].id for rsrc_name in
curr_name_translated_dep.required_by(res.name)
)
old_requirers = set(res.needed_by) if res.needed_by else set()
needed_by = old_requirers | new_requirers
res.needed_by = list(needed_by)
for rsrc in reversed(self.dependencies): for rsrc in reversed(self.dependencies):
existing_rsrc_db = self._get_best_existing_rsrc_db(rsrc.name) existing_rsrc_db = self._get_best_existing_rsrc_db(rsrc.name)
if existing_rsrc_db is None: if existing_rsrc_db is None:
update_needed_by(rsrc)
rsrc.current_template_id = self.t.id rsrc.current_template_id = self.t.id
rsrc.store() rsrc.store()
rsrcs[rsrc.name] = rsrc rsrcs[rsrc.name] = rsrc
else: else:
update_needed_by(existing_rsrc_db)
resource.Resource.set_needed_by(
existing_rsrc_db, existing_rsrc_db.needed_by
)
rsrcs[existing_rsrc_db.name] = existing_rsrc_db rsrcs[existing_rsrc_db.name] = existing_rsrc_db
return rsrcs return rsrcs
@ -1477,9 +1461,7 @@ class Stack(collections.Mapping):
res.id) res.id)
ext_rsrcs_db = self.db_active_resources_get() ext_rsrcs_db = self.db_active_resources_get()
for r in self.dependencies: for r in self.dependencies:
r.needed_by = list(curr_name_translated_dep.required_by(r.id))
r.requires = list(curr_name_translated_dep.requires(r.id)) r.requires = list(curr_name_translated_dep.requires(r.id))
resource.Resource.set_needed_by(ext_rsrcs_db[r.id], r.needed_by)
resource.Resource.set_requires(ext_rsrcs_db[r.id], r.requires) resource.Resource.set_requires(ext_rsrcs_db[r.id], r.requires)
def _compute_convg_dependencies(self, existing_resources, def _compute_convg_dependencies(self, existing_resources,

View File

@ -99,20 +99,6 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
[[2, True], [3, True]]]), # D, C [[2, True], [3, True]]]), # D, C
sorted(stack_db.current_deps['edges'])) sorted(stack_db.current_deps['edges']))
# check if needed_by is stored properly
expected_needed_by = {'A': [3], 'B': [3],
'C': [1, 2],
'D': [], 'E': []}
rsrcs_db = resource_objects.Resource.get_all_by_stack(
stack_db._context, stack_db.id
)
self.assertEqual(5, len(rsrcs_db))
for rsrc_name, rsrc_obj in rsrcs_db.items():
self.assertEqual(sorted(expected_needed_by[rsrc_name]),
sorted(rsrc_obj.needed_by))
self.assertEqual(stack_db.raw_template_id,
rsrc_obj.current_template_id)
# check if sync_points were stored # check if sync_points were stored
for entity_id in [5, 4, 3, 2, 1, stack_db.id]: for entity_id in [5, 4, 3, 2, 1, stack_db.id]:
sync_point = sync_point_object.SyncPoint.get_by_key( sync_point = sync_point_object.SyncPoint.get_by_key(
@ -226,23 +212,6 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
Leaves are at the bottom Leaves are at the bottom
''' '''
# check if needed_by are stored properly
# For A & B:
# needed_by=C, F
expected_needed_by = {'A': [3, 8], 'B': [3, 8],
'C': [1, 2],
'D': [], 'E': [],
'F': [6, 7],
'G': [], 'H': []}
rsrcs_db = resource_objects.Resource.get_all_by_stack(
stack_db._context, stack_db.id
)
self.assertEqual(8, len(rsrcs_db))
for rsrc_name, rsrc_obj in rsrcs_db.items():
self.assertEqual(sorted(expected_needed_by[rsrc_name]),
sorted(rsrc_obj.needed_by))
# check if sync_points are created for forward traversal # check if sync_points are created for forward traversal
# [F, H, G, A, B, Stack] # [F, H, G, A, B, Stack]
for entity_id in [8, 7, 6, 5, 4, stack_db.id]: for entity_id in [8, 7, 6, 5, 4, stack_db.id]:
@ -321,17 +290,6 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
[[4, False], [3, False]]]), [[4, False], [3, False]]]),
sorted(stack_db.current_deps['edges'])) sorted(stack_db.current_deps['edges']))
expected_needed_by = {'A': [3], 'B': [3],
'C': [1, 2],
'D': [], 'E': []}
rsrcs_db = resource_objects.Resource.get_all_by_stack(
stack_db._context, stack_db.id
)
self.assertEqual(5, len(rsrcs_db))
for rsrc_name, rsrc_obj in rsrcs_db.items():
self.assertEqual(sorted(expected_needed_by[rsrc_name]),
sorted(rsrc_obj.needed_by))
# check if sync_points are created for cleanup traversal # check if sync_points are created for cleanup traversal
# [A, B, C, D, E, Stack] # [A, B, C, D, E, Stack]
for entity_id in [5, 4, 3, 2, 1, stack_db.id]: for entity_id in [5, 4, 3, 2, 1, stack_db.id]:

View File

@ -2461,26 +2461,11 @@ class ResourceTest(common.HeatTestCase):
res.name) res.name)
self.assertEqual(msg, six.text_type(ex)) self.assertEqual(msg, six.text_type(ex))
def test_delete_convergence_updates_needed_by(self):
tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo')
res = generic_rsrc.GenericResource('test_res', tmpl, self.stack)
res.current_template_id = 1
res.status = res.COMPLETE
res.action = res.CREATE
res.store()
res.destroy = mock.Mock()
self._assert_resource_lock(res.id, None, None)
scheduler.TaskRunner(res.delete_convergence, 1,
'engine-007', self.dummy_timeout,
self.dummy_event)()
self.assertItemsEqual([], res.needed_by)
@mock.patch.object(resource_objects.Resource, 'get_obj') @mock.patch.object(resource_objects.Resource, 'get_obj')
def test_update_replacement_data(self, mock_get_obj): def test_update_replacement_data(self, mock_get_obj):
tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo') tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo')
r = generic_rsrc.GenericResource('test_res', tmpl, self.stack) r = generic_rsrc.GenericResource('test_res', tmpl, self.stack)
r.replaced_by = 4 r.replaced_by = 4
r.needed_by = [4, 5]
r.store() r.store()
db_res = mock.MagicMock() db_res = mock.MagicMock()
db_res.current_template_id = 'same_tmpl' db_res.current_template_id = 'same_tmpl'
@ -2489,7 +2474,7 @@ class ResourceTest(common.HeatTestCase):
self.assertTrue(mock_get_obj.called) self.assertTrue(mock_get_obj.called)
self.assertTrue(db_res.select_and_update.called) self.assertTrue(db_res.select_and_update.called)
args, kwargs = db_res.select_and_update.call_args args, kwargs = db_res.select_and_update.call_args
self.assertEqual({'replaces': None, 'needed_by': [4, 5]}, args[0]) self.assertEqual({'replaces': None}, args[0])
self.assertIsNone(kwargs['expected_engine_id']) self.assertIsNone(kwargs['expected_engine_id'])
@mock.patch.object(resource_objects.Resource, 'get_obj') @mock.patch.object(resource_objects.Resource, 'get_obj')