From 521630fa7d4599f2aa14fe5277facccc047d5196 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 23 Jun 2022 16:06:13 -0400 Subject: [PATCH] Mitigate web session consumption If called in parallel, multiple sessions may be opened without the old one having a chance to be closed. Serialize any attempt to concurrently login to keep the sessions down. Change-Id: Id389ba1caf89897b00845be394509d489186272d --- pyghmi/ipmi/oem/lenovo/imm.py | 23 +++++++++++++++-------- pyghmi/redfish/oem/lenovo/xcc.py | 27 +++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/pyghmi/ipmi/oem/lenovo/imm.py b/pyghmi/ipmi/oem/lenovo/imm.py index 69f285e0..c988cb27 100644 --- a/pyghmi/ipmi/oem/lenovo/imm.py +++ b/pyghmi/ipmi/oem/lenovo/imm.py @@ -137,6 +137,7 @@ class IMMClient(object): DEVNO = 'generic.devNo' def __init__(self, ipmicmd): + self.weblogging = False self.ipmicmd = weakref.proxy(ipmicmd) self.updating = False self.imm = ipmicmd.bmc @@ -395,14 +396,20 @@ class IMMClient(object): @property def wc(self): - if (not self._wc or (self._wc.vintage - and self._wc.vintage < util._monotonic_time() - - 30)): - if not self.updating and self._wc: - # in case the existing session is still valid - # dispose of the session - self.weblogout() - self._wc = self.get_webclient() + while self.weblogging: + ipmisession.Session.pause(0.25) + self.weblogging = True + try: + if (not self._wc or (self._wc.vintage + and self._wc.vintage < util._monotonic_time() + - 30)): + if not self.updating and self._wc: + # in case the existing session is still valid + # dispose of the session + self.weblogout() + self._wc = self.get_webclient() + finally: + self.weblogging = False return self._wc def fetch_grouped_properties(self, groupinfo): diff --git a/pyghmi/redfish/oem/lenovo/xcc.py b/pyghmi/redfish/oem/lenovo/xcc.py index 69698879..31f1e6fb 100644 --- a/pyghmi/redfish/oem/lenovo/xcc.py +++ b/pyghmi/redfish/oem/lenovo/xcc.py @@ -92,6 +92,7 @@ class OEMHandler(generic.OEMHandler): super(OEMHandler, self).__init__(sysinfo, sysurl, webclient, cache, gpool) self._wc = None + self.weblogging = False self.updating = False self.datacache = {} @@ -698,12 +699,30 @@ class OEMHandler(generic.OEMHandler): if pool.disks: self._create_array(pool) + def weblogout(self): + if self._wc: + try: + self._wc.grab_json_response(self.logouturl) + except Exception: + pass + self._wc = None + @property def wc(self): - if (not self._wc or (self._wc.vintage - and self._wc.vintage < util._monotonic_time() - - 30)): - self._wc = self.get_webclient() + while self.weblogging: + time.sleep(0.25) + self.weblogging = True + try: + if (not self._wc or (self._wc.vintage + and self._wc.vintage < util._monotonic_time() + - 30)): + if not self.updating and self._wc: + # in case the existing session is still valid + # dispose of the session + self.weblogout() + self._wc = self.get_webclient() + finally: + self.weblogging = False return self._wc def get_webclient(self, login=True):