mirror of
https://github.com/xcat2/confluent.git
synced 2025-01-12 18:59:06 +00:00
Fix cpu churn when web sessions open and idle
It turns out that eventlet.green.threading.Event() doesn't behave very efficiently in this context for whatever reason. Use eventlet.event.Event() instead. It was not used before due to lack of timeout and clear, but that is overcome by disposing of it rather than reusing and using with eventlet.Timeout() to add timeout to wait that doesn't have built in timeout.
This commit is contained in:
parent
4911de81e6
commit
5bcde84e14
30
TODO
30
TODO
@ -33,4 +33,32 @@ KeyError: ''
|
||||
-read exclusive and full exclusive console access modes
|
||||
-when an http session exists, confluent cpu usage on my vm idles at 2 %.
|
||||
profile exactly what is spinning and try to make it nicer
|
||||
- an ipmi console was once stuck in 'connecting' state, no idea how
|
||||
- an ipmi console was once stuck in 'connecting' state, no idea how, this traceback might have occurred:
|
||||
Traceback (most recent call last):
|
||||
File "/usr/lib/python2.6/site-packages/eventlet/hubs/hub.py", line 346, in fire_timers
|
||||
timer()
|
||||
File "/usr/lib/python2.6/site-packages/eventlet/hubs/timer.py", line 56, in __call__
|
||||
cb(*args, **kw)
|
||||
File "/usr/lib/python2.6/site-packages/eventlet/semaphore.py", line 121, in _do_acquire
|
||||
waiter.switch()
|
||||
File "/usr/lib/python2.6/site-packages/eventlet/greenthread.py", line 194, in main
|
||||
result = function(*args, **kwargs)
|
||||
File "/usr/lib/python2.6/site-packages/confluent/consoleserver.py", line 177, in _connect_backend
|
||||
self._console.connect(self.get_console_output)
|
||||
File "/usr/lib/python2.6/site-packages/confluent/plugins/hardwaremanagement/ipmi.py", line 143, in connect
|
||||
iohandler=self.handle_data)
|
||||
File "/usr/lib/python2.6/site-packages/pyghmi/ipmi/console.py", line 65, in __init__
|
||||
session.Session.wait_for_rsp(0)
|
||||
File "/usr/lib/python2.6/site-packages/pyghmi/ipmi/private/session.py", line 914, in wait_for_rsp
|
||||
cls._route_ipmiresponse(sockaddr, data)
|
||||
File "/usr/lib/python2.6/site-packages/pyghmi/ipmi/private/session.py", line 991, in _route_ipmiresponse
|
||||
sockaddr=sockaddr)
|
||||
File "/usr/lib/python2.6/site-packages/pyghmi/ipmi/private/session.py", line 1035, in _handle_ipmi_packet
|
||||
self._handle_ipmi2_packet(data)
|
||||
File "/usr/lib/python2.6/site-packages/pyghmi/ipmi/private/session.py", line 1063, in _handle_ipmi2_packet
|
||||
self.k1, rawdata[4:-12], hashlib.sha1).digest()[:12]
|
||||
File "/usr/lib64/python2.6/hmac.py", line 133, in new
|
||||
return HMAC(key, msg, digestmod)
|
||||
File "/usr/lib64/python2.6/hmac.py", line 68, in __init__
|
||||
if len(key) > blocksize:
|
||||
TypeError: object of type 'NoneType' has no len()
|
||||
|
@ -27,7 +27,7 @@ import confluent.interface.console as conapi
|
||||
import confluent.log as log
|
||||
import confluent.core as plugin
|
||||
import eventlet
|
||||
import eventlet.green.threading as threading
|
||||
import eventlet.event
|
||||
import random
|
||||
import traceback
|
||||
|
||||
@ -416,7 +416,7 @@ class ConsoleSession(object):
|
||||
self.username = username
|
||||
connect_node(node, configmanager)
|
||||
_handled_consoles[consk].attachuser(username)
|
||||
self._evt = threading.Event()
|
||||
self._evt = None
|
||||
self.node = node
|
||||
self.conshdl = _handled_consoles[consk]
|
||||
self.write = _handled_consoles[consk].write
|
||||
@ -448,7 +448,8 @@ class ConsoleSession(object):
|
||||
for data, we must maintain data in a buffer until retrieved
|
||||
"""
|
||||
self.databuffer.append(data)
|
||||
self._evt.set()
|
||||
if self._evt:
|
||||
self._evt.send()
|
||||
|
||||
def get_next_output(self, timeout=45):
|
||||
"""Poll for next available output on this console.
|
||||
@ -457,10 +458,13 @@ class ConsoleSession(object):
|
||||
at least one case where we don't have that luxury
|
||||
"""
|
||||
self.reaper.cancel()
|
||||
if self._evt:
|
||||
raise Exception('get_next_output is not re-entrant')
|
||||
if not self.databuffer:
|
||||
self._evt.wait(timeout)
|
||||
if self._evt is not None:
|
||||
self._evt.clear()
|
||||
self._evt = eventlet.event.Event()
|
||||
with eventlet.Timeout(timeout, False):
|
||||
self._evt.wait()
|
||||
self._evt = None
|
||||
if not self.databuffer:
|
||||
self.reaper = eventlet.spawn_after(15, self.destroy)
|
||||
return ""
|
||||
|
Loading…
x
Reference in New Issue
Block a user