From e52c0e34050cfc344401e48cbac80c239f5fd8a2 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 16 Sep 2016 16:01:43 -0400 Subject: [PATCH] Improve SOL responsiveness In a multi-SOL multiplex case, keepalives could bring the whole thing to a grinding halt. Fix this by having a way to request raw_command do 'waitall', which is really just running wait_for_rsp recursively, as used to happen. This is not done by default as for normal synchronous requests, it is a much more expensive approach at scale. Reserve it for the special case of wait_for_rsp which should not hang up on any one response going south. Change-Id: If8890bf959c2376f58c2b36f0445a5b800280b2b --- pyghmi/ipmi/private/session.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/pyghmi/ipmi/private/session.py b/pyghmi/ipmi/private/session.py index cfa34944..fd7a7d0c 100644 --- a/pyghmi/ipmi/private/session.py +++ b/pyghmi/ipmi/private/session.py @@ -671,14 +671,20 @@ class Session(object): incrementtime += 1 return cumulativetime + 1 - def _cmdwait(self): + def _cmdwait(self, waitall=False): while self._isincommand(): - _io_wait(self._isincommand(), self.sockaddr, self.evq) + if waitall: + Session.wait_for_rsp(self._isincommand()) + else: + _io_wait(self._isincommand(), self.sockaddr, self.evq) - def awaitresponse(self, retry): + def awaitresponse(self, retry, waitall=False): while retry and self.lastresponse is None and self.logged: timeout = self.expiration - _monotonic_time() - _io_wait(timeout, self.sockaddr) + if waitall: + Session.wait_for_rsp(timeout) + else: + _io_wait(timeout, self.sockaddr) while self.iterwaiters: waiter = self.iterwaiters.pop() waiter({'success': True}) @@ -695,10 +701,11 @@ class Session(object): data=(), retry=True, delay_xmit=None, - timeout=None): + timeout=None, + waitall=False): if not self.logged: raise exc.IpmiException('Session no longer connected') - self._cmdwait() + self._cmdwait(waitall) if not self.logged: raise exc.IpmiException('Session no longer connected') self.incommand = _monotonic_time() + self._getmaxtimeout() @@ -719,7 +726,7 @@ class Session(object): #of only the constructor needing a callback. From then on, #synchronous usage of the class acts in a greenthread style governed by #order of data on the network - self.awaitresponse(retry) + self.awaitresponse(retry, waitall) lastresponse = self.lastresponse self.incommand = False if retry and lastresponse is None: @@ -1149,7 +1156,7 @@ class Session(object): if self.incommand: # if currently in command, no cause to keepalive return - self.raw_command(netfn=6, command=1) + self.raw_command(netfn=6, command=1, waitall=True) else: kaids = list(self._customkeepalives.keys()) for keepalive in kaids: @@ -1162,6 +1169,7 @@ class Session(object): # raw command ultimately caused a keepalive to # deregister continue + cmd['waitall'] = True callback(self.raw_command(**cmd)) except exc.IpmiException: self._mark_broken()