Optimize get_ports with QoS extension
Apply qos resource extend func for a full list of ports,
not for each port individually, thus avoiding DB queries for each
individual port.
This should drastically improve port list time in case of many
ports/network with QoS policies assigned.
Change-Id: I1d0b3975ae6e92e34e9da20a0e26ce024422d332
Closes-Bug: #1905726
(cherry picked from commit 2a6fd9d44d
)
This commit is contained in:
parent
112d82aad0
commit
5a60a3e414
|
@ -102,6 +102,33 @@ class QoSPlugin(qos.QoSPluginBase):
|
||||||
if not qos_id:
|
if not qos_id:
|
||||||
return port_res
|
return port_res
|
||||||
|
|
||||||
|
if port_res.get('bulk'):
|
||||||
|
port_res['resource_request'] = {
|
||||||
|
'qos_id': qos_id,
|
||||||
|
'network_id': port_db.network_id,
|
||||||
|
'vnic_type': port_res[portbindings.VNIC_TYPE]}
|
||||||
|
return port_res
|
||||||
|
|
||||||
|
min_bw_rules = rule_object.QosMinimumBandwidthRule.get_objects(
|
||||||
|
context.get_admin_context(), qos_policy_id=qos_id)
|
||||||
|
resources = QoSPlugin._get_resources(min_bw_rules)
|
||||||
|
if not resources:
|
||||||
|
return port_res
|
||||||
|
|
||||||
|
segments = network_object.NetworkSegment.get_objects(
|
||||||
|
context.get_admin_context(), network_id=port_db.network_id)
|
||||||
|
traits = QoSPlugin._get_traits(port_res[portbindings.VNIC_TYPE],
|
||||||
|
segments)
|
||||||
|
if not traits:
|
||||||
|
return port_res
|
||||||
|
|
||||||
|
port_res['resource_request'] = {
|
||||||
|
'required': traits,
|
||||||
|
'resources': resources}
|
||||||
|
return port_res
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_resources(min_bw_rules):
|
||||||
resources = {}
|
resources = {}
|
||||||
# NOTE(ralonsoh): we should move this translation dict to n-lib.
|
# NOTE(ralonsoh): we should move this translation dict to n-lib.
|
||||||
rule_direction_class = {
|
rule_direction_class = {
|
||||||
|
@ -110,35 +137,71 @@ class QoSPlugin(qos.QoSPluginBase):
|
||||||
nl_constants.EGRESS_DIRECTION:
|
nl_constants.EGRESS_DIRECTION:
|
||||||
pl_constants.CLASS_NET_BW_EGRESS_KBPS
|
pl_constants.CLASS_NET_BW_EGRESS_KBPS
|
||||||
}
|
}
|
||||||
min_bw_rules = rule_object.QosMinimumBandwidthRule.get_objects(
|
|
||||||
context.get_admin_context(), qos_policy_id=qos_id)
|
|
||||||
for rule in min_bw_rules:
|
for rule in min_bw_rules:
|
||||||
resources[rule_direction_class[rule.direction]] = rule.min_kbps
|
resources[rule_direction_class[rule.direction]] = rule.min_kbps
|
||||||
if not resources:
|
return resources
|
||||||
return port_res
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_traits(vnic_type, segments):
|
||||||
|
# TODO(lajoskatona): Change to handle all segments when any traits
|
||||||
|
# support will be available. See Placement spec:
|
||||||
|
# https://review.opendev.org/565730
|
||||||
|
first_segment = segments[0]
|
||||||
|
if not first_segment or not first_segment.physical_network:
|
||||||
|
return []
|
||||||
|
physnet_trait = pl_utils.physnet_trait(
|
||||||
|
first_segment.physical_network)
|
||||||
# NOTE(ralonsoh): we should not rely on the current execution order of
|
# NOTE(ralonsoh): we should not rely on the current execution order of
|
||||||
# the port extending functions. Although here we have
|
# the port extending functions. Although here we have
|
||||||
# port_res[VNIC_TYPE], we should retrieve this value from the port DB
|
# port_res[VNIC_TYPE], we should retrieve this value from the port DB
|
||||||
# object instead.
|
# object instead.
|
||||||
vnic_trait = pl_utils.vnic_type_trait(
|
vnic_trait = pl_utils.vnic_type_trait(vnic_type)
|
||||||
port_res[portbindings.VNIC_TYPE])
|
|
||||||
|
|
||||||
# TODO(lajoskatona): Change to handle all segments when any traits
|
return [physnet_trait, vnic_trait]
|
||||||
# support will be available. See Placement spec:
|
|
||||||
# https://review.opendev.org/565730
|
|
||||||
first_segment = network_object.NetworkSegment.get_objects(
|
|
||||||
context.get_admin_context(), network_id=port_db.network_id)[0]
|
|
||||||
|
|
||||||
if not first_segment or not first_segment.physical_network:
|
@staticmethod
|
||||||
return port_res
|
# TODO(obondarev): use neutron_lib constant
|
||||||
physnet_trait = pl_utils.physnet_trait(
|
@resource_extend.extends(['ports_bulk'])
|
||||||
first_segment.physical_network)
|
def _extend_port_resource_request_bulk(ports_res, noop):
|
||||||
|
"""Add resource request to a list of ports."""
|
||||||
|
min_bw_rules = dict()
|
||||||
|
net_segments = dict()
|
||||||
|
|
||||||
|
for port_res in ports_res:
|
||||||
|
if port_res.get('resource_request') is None:
|
||||||
|
continue
|
||||||
|
qos_id = port_res['resource_request'].pop('qos_id', None)
|
||||||
|
if not qos_id:
|
||||||
|
port_res['resource_request'] = None
|
||||||
|
continue
|
||||||
|
|
||||||
|
net_id = port_res['resource_request'].pop('network_id')
|
||||||
|
vnic_type = port_res['resource_request'].pop('vnic_type')
|
||||||
|
|
||||||
|
if qos_id not in min_bw_rules:
|
||||||
|
rules = rule_object.QosMinimumBandwidthRule.get_objects(
|
||||||
|
context.get_admin_context(), qos_policy_id=qos_id)
|
||||||
|
min_bw_rules[qos_id] = rules
|
||||||
|
|
||||||
|
resources = QoSPlugin._get_resources(min_bw_rules[qos_id])
|
||||||
|
if not resources:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if net_id not in net_segments:
|
||||||
|
segments = network_object.NetworkSegment.get_objects(
|
||||||
|
context.get_admin_context(),
|
||||||
|
network_id=net_id)
|
||||||
|
net_segments[net_id] = segments
|
||||||
|
|
||||||
|
traits = QoSPlugin._get_traits(vnic_type, net_segments[net_id])
|
||||||
|
if not traits:
|
||||||
|
continue
|
||||||
|
|
||||||
port_res['resource_request'] = {
|
port_res['resource_request'] = {
|
||||||
'required': [physnet_trait, vnic_trait],
|
'required': traits,
|
||||||
'resources': resources}
|
'resources': resources}
|
||||||
return port_res
|
|
||||||
|
return ports_res
|
||||||
|
|
||||||
def _get_ports_with_policy(self, context, policy):
|
def _get_ports_with_policy(self, context, policy):
|
||||||
networks_ids = policy.get_bound_networks()
|
networks_ids = policy.get_bound_networks()
|
||||||
|
|
Loading…
Reference in New Issue