From 80d4518a4982ba8d08005d8a68e18be42fe5b2e0 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 6 Feb 2014 09:27:38 -0500 Subject: [PATCH] Remove more vestiges of the thread support Also, remove a required function from console interface. Now a plugin is only responsible for their thread behavior and never responsible for the consoleserver mechanism requirement for helping user session do polling IO. This is additionally great because it means the coordination is contained to each session object and many client connections are not causing multiple calls to iterate the wait loop. --- confluent/consoleserver.py | 15 +++-------- plugins/hardwaremanagement/ipmi.py | 41 +++++++++--------------------- 2 files changed, 16 insertions(+), 40 deletions(-) diff --git a/confluent/consoleserver.py b/confluent/consoleserver.py index c9061545..e9c791bc 100644 --- a/confluent/consoleserver.py +++ b/confluent/consoleserver.py @@ -13,6 +13,7 @@ import confluent.util as util import eventlet import eventlet.green.threading as threading import random +import time _handled_consoles = {} @@ -160,25 +161,17 @@ class ConsoleSession(object): at least one case where we don't have that luxury """ self.reaper.cancel() - currtime = util.monotonic_time() - deadline = currtime + 45 try: - while len(self.databuffer) == 0 and currtime < deadline: - timeo = deadline - currtime - # change to a threading event object - # got_data will trigger this function to move - if self._evt is None: - self._evt = threading.Event() + if len(self.databuffer) == 0: self._evt.wait(timeout) - self.conshdl._console.wait_for_data(timeout=timeo) - currtime = util.monotonic_time() except TypeError: import traceback traceback.print_exc() return "" retval = self.databuffer self.databuffer = "" - self._evt.clear() + if self._evt is not None: + self._evt.clear() self.reaper = eventlet.spawn_after(15, self.destroy) return retval diff --git a/plugins/hardwaremanagement/ipmi.py b/plugins/hardwaremanagement/ipmi.py index 5515ac26..0f22e693 100644 --- a/plugins/hardwaremanagement/ipmi.py +++ b/plugins/hardwaremanagement/ipmi.py @@ -13,18 +13,12 @@ import pyghmi.ipmi.command as ipmicommand console.session.select = eventlet.green.select console.session.threading = eventlet.green.threading -tmptimeout = None _ipmithread = None def _ipmi_evtloop(): - global tmptimeout - while (1): + while True: try: - if tmptimeout is not None: - console.session.Session.wait_for_rsp(timeout=tmptimeout) - tmptimeout = None - else: - console.session.Session.wait_for_rsp(timeout=600) + console.session.Session.wait_for_rsp(timeout=600) except: import traceback traceback.print_exc() @@ -91,36 +85,16 @@ class IpmiConsole(conapi.Console): self.datacallback(data) def connect(self,callback): - global _ipmithread self.datacallback = callback - self.solconnection=console.Console(bmc=self.bmc, port=self.port, + self.solconnection = console.Console(bmc=self.bmc, port=self.port, userid=self.username, password=self.password, kg=self.kg, force=True, iohandler=self.handle_data) - if _ipmithread is None: - _ipmithread = eventlet.spawn(_ipmi_evtloop) def write(self, data): self.solconnection.send_data(data) - def wait_for_data(self, timeout=600): - """Wait for some network event. - - This is currently not guaranteed to actually have data when - return. This is supposed to be something more appropriate - than sleep(0), but only marginally so. - """ - # reason for this is that we currently nicely pass through the callback - # straight to ipmi library. To implement this accurately, easiest path - # would be to add a layer through the callback. IMO there isn't enough - # value in assuring data coming back to bother with making the stack - # taller than it has to be - #TODO: a channel for the ipmithread to tug back instead of busy wait - #while tmptimeout is not None: - # eventlet.sleep(0) - console.session.Session.wait_for_rsp(timeout=timeout) - class IpmiIterator(object): def __init__(self, operator, nodes, element, cfg, inputdata): @@ -223,7 +197,14 @@ class IpmiHandler(object): +def initthread(): + global _ipmithread + if _ipmithread is None: + _ipmithread = eventlet.spawn(_ipmi_evtloop) + + def create(nodes, element, configmanager, inputdata): + initthread() if element == [ '_console', 'session' ]: if len(nodes) > 1: raise Exception("_console/session does not support multiple nodes") @@ -232,10 +213,12 @@ def create(nodes, element, configmanager, inputdata): return IpmiIterator('update', nodes, element, configmanager, inputdata) def update(nodes, element, configmanager, inputdata): + initthread() return create(nodes, element, configmanager, inputdata) def retrieve(nodes, element, configmanager, inputdata): + initthread() return IpmiIterator('read', nodes, element, configmanager, inputdata)