Caching ResourceCollectionBase::get_members()

Right now each time 'get_members()' method gets called a new list
is created with fresh instantiation of element type resources.

This ought to be optimized by returning the cached result in
case of repetitive invocations and should the need be to fetch
the refreshed result it would ideally reinstantiate the member
resources of the collection. Also, in case of any member resource
element within collection is being marked as stale, this handles
properly to return the refresh'ed resource if that is accessed
through this 'get_members()' method of the referenced resource
collection instance:

    res_collection_inst.get_members()[any_index].some_attr

to access the current (or live) value of 'some_attr' w/o the need
of recreating (read re-instantiating) the constituent element
resource instance.

Change-Id: I7885143baa430d4e088f99febd6f8bc1a4f99aea
This commit is contained in:
Debayan Ray 2018-08-27 09:15:00 +00:00
parent 9316afa5f6
commit 3ed9aa95c8
6 changed files with 43 additions and 3 deletions

View File

@ -325,6 +325,8 @@ class ResourceCollectionBase(ResourceBase):
adapter=utils.get_members_identities)
"""A tuple with the members identities"""
_members = None # caching variable
def __init__(self, connector, path, redfish_version=None):
"""A class representing the base of any Redfish resource collection
@ -365,4 +367,19 @@ class ResourceCollectionBase(ResourceBase):
:returns: A list of ``_resource_type`` objects
"""
return [self.get_member(id_) for id_ in self.members_identities]
if self._members is None:
self._members = [self.get_member(id_)
for id_ in self.members_identities]
for m in self._members:
m.refresh(force=False)
return self._members
def _do_refresh(self, force=False):
"""Do refresh related activities.
Undefine the `_members` attribute here for fresh evaluation in
subsequent calls to `get_members()` method. Other similar activities
can also follow in future, if needed.
"""
self._members = None

View File

@ -83,4 +83,5 @@ class EthernetInterfaceCollection(base.ResourceCollectionBase):
greedy-refresh not done for them unless forced by ``force``
argument.
"""
super(EthernetInterfaceCollection, self)._do_refresh(force)
self._summary = None

View File

@ -155,5 +155,6 @@ class ProcessorCollection(base.ResourceCollectionBase):
greedy-refresh not done for them unless forced by ``force``
argument.
"""
super(ProcessorCollection, self)._do_refresh(force)
# Reset summary attribute
self._summary = None

View File

@ -81,6 +81,7 @@ class SimpleStorageCollection(base.ResourceCollectionBase):
return self._max_size_bytes
def _do_refresh(self, force=False):
super(SimpleStorageCollection, self)._do_refresh(force)
# Note(deray): undefine the attribute here for fresh creation in
# subsequent calls to it's exposed property.
self._max_size_bytes = None

View File

@ -53,5 +53,6 @@ class VolumeCollection(base.ResourceCollectionBase):
return self._max_size_bytes
def _do_refresh(self, force=False):
super(VolumeCollection, self)._do_refresh(force)
# invalidate the attribute
self._max_size_bytes = None

View File

@ -129,10 +129,9 @@ class ResourceCollectionBaseTestCase(base.TestCase):
self.test_resource_collection.get_member, '2')
self.conn.get.assert_called_once_with(path='Fakes/2')
def test_get_members(self):
def _validate_get_members_result(self, member_ids):
# | GIVEN |
# setting some valid member paths
member_ids = ('1', '2')
self.test_resource_collection.members_identities = member_ids
# | WHEN |
result = self.test_resource_collection.get_members()
@ -143,6 +142,26 @@ class ResourceCollectionBaseTestCase(base.TestCase):
self.assertTrue(val.identity in member_ids)
self.assertEqual('1.0.x', val.redfish_version)
return result
def test_get_members(self):
self._validate_get_members_result(('1', '2'))
def test_get_members_on_refresh(self):
self._validate_get_members_result(('1', '2'))
# Now emulating the resource invalidate and refresh action!
self.test_resource_collection.invalidate()
self.assertTrue(self.test_resource_collection._is_stale)
self.test_resource_collection.refresh(force=False)
self._validate_get_members_result(('3', '4'))
self.assertFalse(self.test_resource_collection._is_stale)
def test_get_members_caching(self):
result = self._validate_get_members_result(('1', '2'))
self.assertIs(result, self.test_resource_collection.get_members())
TEST_JSON = {
'String': 'a string',