Skip to content

Commit

Permalink
Fixed performance issue in list_permitted_lpars/partitions()
Browse files Browse the repository at this point in the history
Details:

* In zhmcclient version 1.13.0, an optimization was added where list() and
  find_local() were now utilizing the name-to-URI cache when only the
  resource name was specified as a filter argument.
  The Console.list_permitted_lpars/partitions() methods used find_local() to
  look up the parent CPC of the returned LPARs/partitions and specified
  'se-version' as an additional property. However, find_local() uses the
  additional properties only when the resource object was not found in the
  name-to-URI cache. Because of the optimization, the Cpc object was now
  found in the cache, and the 'se-version' property was therefore not
  added anymore.

  The performance degradation was fixed by (1) creating local resource
  objects for the parent CPCs Console.list_permitted_lpars/partitions()
  in order to have better control over the properties they have, and (2) by
  reducing the Cpc objects to one for each real CPC (before we created one
  Cpc object for each Lpar/Partition object.

Signed-off-by: Andreas Maier <maiera@de.ibm.com>
  • Loading branch information
andy-maier committed Jan 28, 2024
1 parent 7bc0965 commit da07dd5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 28 deletions.
11 changes: 11 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ Released: not yet

* Development: Fixed dependency issue with safety 3.0.0 by pinning it.

* Performance: In zhmcclient version 1.13.0, an optimization was added where
list() and find_local() were now utilizing the name-to-URI cache when only the
resource name was specified as a filter argument. This caused the 'se-version'
property to no longer be in the local zhmcclient.Cpc objects that were used
as the parent objects of the Lpar/Partition objects returned by
Console.list_permitted_lpars/partitions() and caused a performance
degradation in the zhmc_lpar_list and zhmc_partition_list Ansible modules due
to repeated "Get CPC Properties" operations for retrieving the 'se-version'
property. This was fixed in the Console.list_permitted_lpars/partitions()
methods.

**Enhancements:**

* Test: Added Python 3.8 with latest package levels to normal tests because
Expand Down
66 changes: 38 additions & 28 deletions zhmcclient/_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,10 @@ def list_permitted_partitions(
self.uri, query_parms_str)
result = self.manager.session.get(uri, resource=self)

cpcs_by_uri = {} # caches local Cpc objects for CPCs already seen
partition_objs = []
if result:
cpc_manager = self.manager.client.cpcs
partition_items = result['partitions']
for partition_item in partition_items:

Expand All @@ -682,18 +684,21 @@ def list_permitted_partitions(
# * cpc-object-uri (CPC property 'object-uri')
# * se-version (CPC property 'se-version') (if >=2.14.1)

# Create a 'skeleton' local Cpc object we can hang the
# Partition objects off of, even if the user does not have
# access permissions to these CPCs. Note that different
# partitions can have different parent CPCs.
cpc_props = {}
if 'se-version' in partition_item:
cpc_props['se-version'] = partition_item['se-version']
cpc = self.manager.client.cpcs.find_local(
partition_item['cpc-name'],
partition_item['cpc-object-uri'],
cpc_props,
)
cpc_uri = partition_item['cpc-object-uri']
try:
cpc = cpcs_by_uri[cpc_uri]
except KeyError:
# Create a 'skeleton' local Cpc object we can hang the
# Partition objects off of, even if the user does not have
# access permissions to these CPCs. Note that different
# partitions can have different parent CPCs.
cpc_props = {}
cpc_props['name'] = partition_item['cpc-name']
if 'se-version' in partition_item:
cpc_props['se-version'] = partition_item['se-version']
cpc = cpc_manager.resource_object(cpc_uri, cpc_props)

cpcs_by_uri[cpc_uri] = cpc

partition_obj = cpc.partitions.resource_object(
partition_item['object-uri'],
Expand Down Expand Up @@ -798,8 +803,10 @@ def list_permitted_lpars(
self.uri, query_parms_str)
result = self.manager.session.get(uri, resource=self)

cpcs_by_uri = {} # caches local Cpc objects for CPCs already seen
lpar_objs = []
if result:
cpc_manager = self.manager.client.cpcs
lpar_items = result['logical-partitions']
for lpar_item in lpar_items:

Expand All @@ -811,18 +818,21 @@ def list_permitted_lpars(
# * cpc-object-uri (CPC property 'object-uri')
# * se-version (CPC property 'se-version') (if >=2.14.1)

# Create a 'skeleton' local Cpc object we can hang the
# Partition objects off of, even if the user does not have
# access permissions to these CPCs. Note that different
# partitions can have different parent CPCs.
cpc_props = {}
if 'se-version' in lpar_item:
cpc_props['se-version'] = lpar_item['se-version']
cpc = self.manager.client.cpcs.find_local(
lpar_item['cpc-name'],
lpar_item['cpc-object-uri'],
cpc_props,
)
cpc_uri = lpar_item['cpc-object-uri']
try:
cpc = cpcs_by_uri[cpc_uri]
except KeyError:
# Create a 'skeleton' local Cpc object we can hang the
# Partition objects off of, even if the user does not have
# access permissions to these CPCs. Note that different
# partitions can have different parent CPCs.
cpc_props = {}
cpc_props['name'] = lpar_item['cpc-name']
if 'se-version' in lpar_item:
cpc_props['se-version'] = lpar_item['se-version']
cpc = cpc_manager.resource_object(cpc_uri, cpc_props)

cpcs_by_uri[cpc_uri] = cpc

lpar_props = {
'name': lpar_item['name'],
Expand Down Expand Up @@ -970,13 +980,13 @@ def list_permitted_adapters(

# Group the returned adapters by CPC
adapter_items_by_cpc = {}
cpcs_by_cpc = {}
cpcs_by_name = {}
for adapter_item in result['adapters']:
cpc_name = adapter_item['cpc-name']
if cpc_name not in adapter_items_by_cpc:
adapter_items_by_cpc[cpc_name] = []
adapter_items_by_cpc[cpc_name].append(adapter_item)
if cpc_name not in cpcs_by_cpc:
if cpc_name not in cpcs_by_name:
# Create a 'skeleton' local Cpc object we can hang the
# Adapter objects off of, even if the user does not have
# access permissions to these CPCs. Note that different
Expand All @@ -991,10 +1001,10 @@ def list_permitted_adapters(
uri=adapter_item['cpc-object-uri'],
properties=cpc_props,
)
cpcs_by_cpc[cpc_name] = cpc
cpcs_by_name[cpc_name] = cpc

# Process the returned adapters
for cpc_name, cpc in cpcs_by_cpc.items():
for cpc_name, cpc in cpcs_by_name.items():
adapter_items = adapter_items_by_cpc[cpc_name]
adapter_manager = cpc.adapters
if full_properties:
Expand Down

0 comments on commit da07dd5

Please sign in to comment.