Skip _exclude_nested_providers() if not nested
In rocky cycle, 'GET /allocation_candidates' started to be aware of nested providers from microversion 1.29, namely, it can have multiple allocations from multiple resource providers in the same tree in the allocation requests. To keep the behavior of microversion before 1.29, it added a filters to exculde nested providers being unaware of the nested architecture. However that function "_exclude_nested_providers()" is very heavy and is executed even if there is no nested provider in the environment when microversion < 1.29. This patch changes it to skip it if there is no nested provider. Since _exclude_nested_providers() should be done before limitting the candidates, this patch also moves it from hander file to the deeper layer. Change-Id: I4efdc65395e69a6d33fba927018d003cce26fa68 Story: 2005669 Task: 30980
This commit is contained in:
parent
5702625561
commit
727fb88dcc
placement
@ -204,40 +204,6 @@ def _transform_provider_summaries(p_sums, requests, want_version):
|
||||
return ret
|
||||
|
||||
|
||||
def _exclude_nested_providers(alloc_cands):
|
||||
"""Exclude allocation requests and provider summaries for old microversions
|
||||
if they involve more than one provider from the same tree.
|
||||
"""
|
||||
# Build a temporary dict, keyed by root RP UUID of sets of UUIDs of all RPs
|
||||
# in that tree.
|
||||
tree_rps_by_root = collections.defaultdict(set)
|
||||
for ps in alloc_cands.provider_summaries:
|
||||
rp_uuid = ps.resource_provider.uuid
|
||||
root_uuid = ps.resource_provider.root_provider_uuid
|
||||
tree_rps_by_root[root_uuid].add(rp_uuid)
|
||||
# We use this to get a list of sets of providers in each tree
|
||||
tree_sets = list(tree_rps_by_root.values())
|
||||
|
||||
for a_req in alloc_cands.allocation_requests[:]:
|
||||
alloc_rp_uuids = set([
|
||||
arr.resource_provider.uuid for arr in a_req.resource_requests])
|
||||
# If more than one allocation is provided by the same tree, kill
|
||||
# that allocation request.
|
||||
if any(len(tree_set & alloc_rp_uuids) > 1 for tree_set in tree_sets):
|
||||
alloc_cands.allocation_requests.remove(a_req)
|
||||
|
||||
# Exclude eliminated providers from the provider summaries.
|
||||
all_rp_uuids = set()
|
||||
for a_req in alloc_cands.allocation_requests:
|
||||
all_rp_uuids |= set(
|
||||
arr.resource_provider.uuid for arr in a_req.resource_requests)
|
||||
for ps in alloc_cands.provider_summaries[:]:
|
||||
if ps.resource_provider.uuid not in all_rp_uuids:
|
||||
alloc_cands.provider_summaries.remove(ps)
|
||||
|
||||
return alloc_cands
|
||||
|
||||
|
||||
def _transform_allocation_candidates(alloc_cands, requests, want_version):
|
||||
"""Turn supplied AllocationCandidates object into a dict containing
|
||||
allocation requests and provider summaries.
|
||||
@ -247,10 +213,6 @@ def _transform_allocation_candidates(alloc_cands, requests, want_version):
|
||||
'provider_summaries': <PROVIDER_SUMMARIES>,
|
||||
}
|
||||
"""
|
||||
# exclude nested providers with old microversions
|
||||
if not want_version.matches((1, 29)):
|
||||
alloc_cands = _exclude_nested_providers(alloc_cands)
|
||||
|
||||
if want_version.matches((1, 12)):
|
||||
a_reqs = _transform_allocation_requests_dict(
|
||||
alloc_cands.allocation_requests)
|
||||
@ -312,9 +274,13 @@ def list_allocation_candidates(req):
|
||||
'The "group_policy" parameter is required when specifying '
|
||||
'more than one "resources{N}" parameter.')
|
||||
|
||||
# We can't be aware of nested architecture with old microversions
|
||||
nested_aware = want_version.matches((1, 29))
|
||||
|
||||
try:
|
||||
cands = ac_obj.AllocationCandidates.get_by_requests(
|
||||
context, requests, limit=limit, group_policy=group_policy)
|
||||
context, requests, limit=limit, group_policy=group_policy,
|
||||
nested_aware=nested_aware)
|
||||
except exception.ResourceClassNotFound as exc:
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
'Invalid resource class in resources parameter: %(error)s' %
|
||||
|
@ -53,7 +53,8 @@ class AllocationCandidates(object):
|
||||
self.provider_summaries = provider_summaries
|
||||
|
||||
@classmethod
|
||||
def get_by_requests(cls, context, requests, limit=None, group_policy=None):
|
||||
def get_by_requests(cls, context, requests, limit=None, group_policy=None,
|
||||
nested_aware=True):
|
||||
"""Returns an AllocationCandidates object containing all resource
|
||||
providers matching a set of supplied resource constraints, with a set
|
||||
of allocation requests constructed from that list of resource
|
||||
@ -76,12 +77,16 @@ class AllocationCandidates(object):
|
||||
other. If the value is "isolate", we will filter
|
||||
out allocation requests where any such
|
||||
RequestGroups are satisfied by the same RP.
|
||||
:param nested_aware: If False, we are blind to nested architecture and
|
||||
can't pick resources from multiple providers even
|
||||
if they come from the same tree.
|
||||
:return: An instance of AllocationCandidates with allocation_requests
|
||||
and provider_summaries satisfying `requests`, limited
|
||||
according to `limit`.
|
||||
"""
|
||||
alloc_reqs, provider_summaries = cls._get_by_requests(
|
||||
context, requests, limit=limit, group_policy=group_policy)
|
||||
context, requests, limit=limit, group_policy=group_policy,
|
||||
nested_aware=nested_aware)
|
||||
return cls(
|
||||
allocation_requests=alloc_reqs,
|
||||
provider_summaries=provider_summaries,
|
||||
@ -175,7 +180,7 @@ class AllocationCandidates(object):
|
||||
# reader when that migration is no longer happening.
|
||||
@db_api.placement_context_manager.writer
|
||||
def _get_by_requests(cls, context, requests, limit=None,
|
||||
group_policy=None):
|
||||
group_policy=None, nested_aware=True):
|
||||
# TODO(jaypipes): Make a RequestGroupContext object and put these
|
||||
# pieces of information in there, passing the context to the various
|
||||
# internal functions handling that part of the request.
|
||||
@ -214,6 +219,10 @@ class AllocationCandidates(object):
|
||||
alloc_request_objs, summary_objs = _merge_candidates(
|
||||
candidates, group_policy=group_policy)
|
||||
|
||||
if not nested_aware and has_trees:
|
||||
alloc_request_objs, summary_objs = _exclude_nested_providers(
|
||||
alloc_request_objs, summary_objs)
|
||||
|
||||
return cls._limit_results(context, alloc_request_objs, summary_objs,
|
||||
limit)
|
||||
|
||||
@ -980,3 +989,37 @@ def _satisfies_group_policy(areqs, group_policy, num_granular_groups):
|
||||
'request (%d): %s',
|
||||
num_granular_groups_in_areqs, num_granular_groups, str(areqs))
|
||||
return False
|
||||
|
||||
|
||||
def _exclude_nested_providers(allocation_requests, provider_summaries):
|
||||
"""Exclude allocation requests and provider summaries for old microversions
|
||||
if they involve more than one provider from the same tree.
|
||||
"""
|
||||
# Build a temporary dict, keyed by root RP UUID of sets of UUIDs of all RPs
|
||||
# in that tree.
|
||||
tree_rps_by_root = collections.defaultdict(set)
|
||||
for ps in provider_summaries:
|
||||
rp_uuid = ps.resource_provider.uuid
|
||||
root_uuid = ps.resource_provider.root_provider_uuid
|
||||
tree_rps_by_root[root_uuid].add(rp_uuid)
|
||||
# We use this to get a list of sets of providers in each tree
|
||||
tree_sets = list(tree_rps_by_root.values())
|
||||
|
||||
for a_req in allocation_requests[:]:
|
||||
alloc_rp_uuids = set([
|
||||
arr.resource_provider.uuid for arr in a_req.resource_requests])
|
||||
# If more than one allocation is provided by the same tree, kill
|
||||
# that allocation request.
|
||||
if any(len(tree_set & alloc_rp_uuids) > 1 for tree_set in tree_sets):
|
||||
allocation_requests.remove(a_req)
|
||||
|
||||
# Exclude eliminated providers from the provider summaries.
|
||||
all_rp_uuids = set()
|
||||
for a_req in allocation_requests:
|
||||
all_rp_uuids |= set(
|
||||
arr.resource_provider.uuid for arr in a_req.resource_requests)
|
||||
for ps in provider_summaries[:]:
|
||||
if ps.resource_provider.uuid not in all_rp_uuids:
|
||||
provider_summaries.remove(ps)
|
||||
|
||||
return allocation_requests, provider_summaries
|
||||
|
Loading…
x
Reference in New Issue
Block a user