Efficient passing of attrs during traversals
Two improvements: Do not iterate through stack outputs when determining what attributes to send as input_data to the next resources in a traversal; it is at best extra processing and at worse results in extra attributes being included in input_data. Do not re-resolve attributes / re-calculate input_data when we already have it. I.e., when a resource constructs input_data to send to a requirer resource, that same input_data may be used for all other requirer resources. Change-Id: I64089fb0774c10f172d986c3f87090e91cb3f263 Closes-Bug: #1656125
This commit is contained in:
parent
4507322675
commit
efabef60d0
@ -203,9 +203,13 @@ class CheckResource(object):
|
|||||||
# for the next traversal.
|
# for the next traversal.
|
||||||
graph_key = (rsrc.replaces, is_update)
|
graph_key = (rsrc.replaces, is_update)
|
||||||
|
|
||||||
def _get_input_data(req, fwd):
|
def _get_input_data(req, fwd, input_forward_data=None):
|
||||||
if fwd:
|
if fwd:
|
||||||
return construct_input_data(rsrc, stack)
|
if input_forward_data is None:
|
||||||
|
return construct_input_data(rsrc, stack)
|
||||||
|
else:
|
||||||
|
# do not re-resolve attrs
|
||||||
|
return input_forward_data
|
||||||
else:
|
else:
|
||||||
# Don't send data if initiating clean-up for self i.e.
|
# Don't send data if initiating clean-up for self i.e.
|
||||||
# initiating delete of a replaced resource
|
# initiating delete of a replaced resource
|
||||||
@ -217,8 +221,11 @@ class CheckResource(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
input_forward_data = None
|
||||||
for req, fwd in deps.required_by(graph_key):
|
for req, fwd in deps.required_by(graph_key):
|
||||||
input_data = _get_input_data(req, fwd)
|
input_data = _get_input_data(req, fwd, input_forward_data)
|
||||||
|
if fwd:
|
||||||
|
input_forward_data = input_data
|
||||||
propagate_check_resource(
|
propagate_check_resource(
|
||||||
cnxt, self._rpc_client, req, current_traversal,
|
cnxt, self._rpc_client, req, current_traversal,
|
||||||
set(graph[(req, fwd)]), graph_key, input_data, fwd,
|
set(graph[(req, fwd)]), graph_key, input_data, fwd,
|
||||||
@ -311,9 +318,7 @@ def _resolve_attributes(dep_attrs, rsrc):
|
|||||||
def construct_input_data(rsrc, curr_stack):
|
def construct_input_data(rsrc, curr_stack):
|
||||||
dep_attrs = curr_stack.get_dep_attrs(
|
dep_attrs = curr_stack.get_dep_attrs(
|
||||||
six.itervalues(curr_stack.resources),
|
six.itervalues(curr_stack.resources),
|
||||||
curr_stack.outputs,
|
rsrc.name)
|
||||||
rsrc.name,
|
|
||||||
curr_stack.t.OUTPUT_VALUE)
|
|
||||||
input_data = {'id': rsrc.id,
|
input_data = {'id': rsrc.id,
|
||||||
'name': rsrc.name,
|
'name': rsrc.name,
|
||||||
'reference_id': rsrc.get_reference_id(),
|
'reference_id': rsrc.get_reference_id(),
|
||||||
|
@ -462,17 +462,14 @@ class Stack(collections.Mapping):
|
|||||||
LOG.warning(_LW("Unable to set parameters StackId identifier"))
|
LOG.warning(_LW("Unable to set parameters StackId identifier"))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_dep_attrs(resources, outputs, resource_name, value_sec):
|
def get_dep_attrs(resources, resource_name):
|
||||||
"""Return the attributes of the specified resource that are referenced.
|
"""Return the attributes of the specified resource that are referenced.
|
||||||
|
|
||||||
Return an iterator over any attributes of the specified resource that
|
Return an iterator over any attributes of the specified resource that
|
||||||
are referenced.
|
are referenced in resources.
|
||||||
"""
|
"""
|
||||||
attr_lists = itertools.chain((res.dep_attrs(resource_name)
|
return set(itertools.chain.from_iterable(
|
||||||
for res in resources),
|
res.dep_attrs(resource_name) for res in resources))
|
||||||
(out.dep_attrs(resource_name)
|
|
||||||
for out in six.itervalues(outputs)))
|
|
||||||
return set(itertools.chain.from_iterable(attr_lists))
|
|
||||||
|
|
||||||
def _get_dependencies(self, ignore_errors=True):
|
def _get_dependencies(self, ignore_errors=True):
|
||||||
"""Return the dependency graph for a list of resources."""
|
"""Return the dependency graph for a list of resources."""
|
||||||
|
@ -192,8 +192,7 @@ class DepAttrsTest(common.HeatTestCase):
|
|||||||
('one_res_several_attrs',
|
('one_res_several_attrs',
|
||||||
dict(tmpl=tmpl3,
|
dict(tmpl=tmpl3,
|
||||||
expected={'AResource': {'attr_A1', 'attr_A2', 'attr_A3',
|
expected={'AResource': {'attr_A1', 'attr_A2', 'attr_A3',
|
||||||
'meta_A1', 'meta_A2', 'out_A1',
|
'meta_A1', 'meta_A2'},
|
||||||
'out_A2'},
|
|
||||||
'BResource': set()})),
|
'BResource': set()})),
|
||||||
('several_res_one_attr',
|
('several_res_one_attr',
|
||||||
dict(tmpl=tmpl4,
|
dict(tmpl=tmpl4,
|
||||||
@ -203,25 +202,19 @@ class DepAttrsTest(common.HeatTestCase):
|
|||||||
'DResource': set()})),
|
'DResource': set()})),
|
||||||
('several_res_several_attrs',
|
('several_res_several_attrs',
|
||||||
dict(tmpl=tmpl5,
|
dict(tmpl=tmpl5,
|
||||||
expected={'AResource': {'attr_A1', 'attr_A2', 'meta_A1',
|
expected={'AResource': {'attr_A1', 'attr_A2', 'meta_A1'},
|
||||||
'attr_A3', 'attr_A4'},
|
'BResource': {'attr_B1', 'attr_B2', 'meta_B2'},
|
||||||
'BResource': {'attr_B1', 'attr_B2', 'meta_B2',
|
|
||||||
'attr_B3'},
|
|
||||||
'CResource': set()})),
|
'CResource': set()})),
|
||||||
('nested_attr',
|
('nested_attr',
|
||||||
dict(tmpl=tmpl6,
|
dict(tmpl=tmpl6,
|
||||||
expected={'AResource': set([(u'flat_dict', u'key2'),
|
expected={'AResource': set([(u'list', 1),
|
||||||
(u'list', 1),
|
(u'nested_dict', u'dict', u'b')]),
|
||||||
(u'nested_dict', u'dict', u'b'),
|
'BResource': set([])})),
|
||||||
(u'nested_dict', u'string')]),
|
|
||||||
'BResource': set(['attr_B3'])})),
|
|
||||||
('several_res_several_attrs_and_all_attrs',
|
('several_res_several_attrs_and_all_attrs',
|
||||||
dict(tmpl=tmpl7,
|
dict(tmpl=tmpl7,
|
||||||
expected={'AResource': {'attr_A1', 'attr_A2', 'meta_A1',
|
expected={'AResource': {'attr_A1', 'attr_A2', 'meta_A1'},
|
||||||
'attr_A3', 'attr_A4'},
|
'BResource': {'attr_B1', 'attr_B2', 'meta_B2'},
|
||||||
'BResource': {'attr_B1', 'attr_B2', 'meta_B2',
|
'CResource': set()}))
|
||||||
'attr_B3'},
|
|
||||||
'CResource': {'foo', 'Foo', 'show'}}))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -234,11 +227,8 @@ class DepAttrsTest(common.HeatTestCase):
|
|||||||
template.Template(parsed_tmpl))
|
template.Template(parsed_tmpl))
|
||||||
|
|
||||||
for res in six.itervalues(self.stack):
|
for res in six.itervalues(self.stack):
|
||||||
outputs = self.stack.outputs
|
|
||||||
resources = six.itervalues(self.stack.resources)
|
resources = six.itervalues(self.stack.resources)
|
||||||
self.assertEqual(self.expected[res.name],
|
self.assertEqual(self.expected[res.name],
|
||||||
self.stack.get_dep_attrs(
|
self.stack.get_dep_attrs(
|
||||||
resources,
|
resources,
|
||||||
outputs,
|
res.name))
|
||||||
res.name,
|
|
||||||
self.stack.t.OUTPUT_VALUE))
|
|
||||||
|
Loading…
Reference in New Issue
Block a user