Use eventlet Event for loopingcall events
This fixes broken logic for finding out how to use green threads. Using threading.Event with eventlet creates useless load related to timers. Change-Id: I62e9f1a7cde8846be368fbec58b8e0825ce02079 Closes-Bug: #1798774
This commit is contained in:
parent
2705800cd3
commit
c2463470f5
|
@ -17,13 +17,12 @@
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from eventlet import event
|
from eventlet import event
|
||||||
from eventlet import greenthread
|
from eventlet import greenthread
|
||||||
|
from eventlet import timeout as eventlettimeout
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import eventletutils
|
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import reflection
|
from oslo_utils import reflection
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
@ -77,51 +76,30 @@ def _safe_wrapper(f, kind, func_name):
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
def _Event():
|
class _Event(object):
|
||||||
if eventletutils.is_monkey_patched('thread'):
|
"""A class that provides consistent eventlet/threading Event API.
|
||||||
return _ThreadingEvent()
|
|
||||||
else:
|
|
||||||
return _GreenEvent()
|
|
||||||
|
|
||||||
|
It's a copy from the oslo_utils repository, as we need the private version
|
||||||
class _ThreadingEvent(object):
|
because we don't want to use the threading.Event version.
|
||||||
def __init__(self):
|
"""
|
||||||
self._abort = threading.Event()
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.clear()
|
||||||
def is_running(self):
|
|
||||||
return not self._abort.is_set()
|
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._abort.clear()
|
self._set = False
|
||||||
|
self._event = event.Event()
|
||||||
|
|
||||||
def wait(self, timeout):
|
def is_set(self):
|
||||||
self._abort.wait(timeout)
|
return self._set
|
||||||
|
|
||||||
def stop(self):
|
def set(self):
|
||||||
self._abort.set()
|
self._set = True
|
||||||
|
self._event.send(True)
|
||||||
|
|
||||||
def done(self):
|
def wait(self, timeout=None):
|
||||||
pass
|
with eventlettimeout.Timeout(timeout, False):
|
||||||
|
self._event.wait()
|
||||||
|
return self.is_set()
|
||||||
class _GreenEvent(object):
|
|
||||||
def __init__(self):
|
|
||||||
self._running = False
|
|
||||||
|
|
||||||
def is_running(self):
|
|
||||||
return self._running
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
self._running = True
|
|
||||||
|
|
||||||
def wait(self, timeout):
|
|
||||||
greenthread.sleep(timeout)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self._running = False
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
self._running = False
|
|
||||||
|
|
||||||
|
|
||||||
class LoopingCallBase(object):
|
class LoopingCallBase(object):
|
||||||
|
@ -136,24 +114,23 @@ class LoopingCallBase(object):
|
||||||
self.f = f
|
self.f = f
|
||||||
self._thread = None
|
self._thread = None
|
||||||
self.done = None
|
self.done = None
|
||||||
self._event = _Event()
|
self._abort = _Event()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _running(self):
|
def _running(self):
|
||||||
return self._event.is_running()
|
return not self._abort.is_set()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self._event.stop()
|
self._abort.set()
|
||||||
|
|
||||||
def wait(self):
|
def wait(self):
|
||||||
return self.done.wait()
|
return self.done.wait()
|
||||||
|
|
||||||
def _on_done(self, gt, *args, **kwargs):
|
def _on_done(self, gt, *args, **kwargs):
|
||||||
self._thread = None
|
self._thread = None
|
||||||
self._event.done()
|
|
||||||
|
|
||||||
def _sleep(self, timeout):
|
def _sleep(self, timeout):
|
||||||
self._event.wait(timeout)
|
self._abort.wait(timeout)
|
||||||
|
|
||||||
def _start(self, idle_for, initial_delay=None, stop_on_exception=True):
|
def _start(self, idle_for, initial_delay=None, stop_on_exception=True):
|
||||||
"""Start the looping
|
"""Start the looping
|
||||||
|
@ -171,7 +148,7 @@ class LoopingCallBase(object):
|
||||||
if self._thread is not None:
|
if self._thread is not None:
|
||||||
raise RuntimeError(self._RUN_ONLY_ONE_MESSAGE)
|
raise RuntimeError(self._RUN_ONLY_ONE_MESSAGE)
|
||||||
self.done = event.Event()
|
self.done = event.Event()
|
||||||
self._event.clear()
|
self._abort.clear()
|
||||||
self._thread = greenthread.spawn(
|
self._thread = greenthread.spawn(
|
||||||
self._run_loop, idle_for,
|
self._run_loop, idle_for,
|
||||||
initial_delay=initial_delay, stop_on_exception=stop_on_exception)
|
initial_delay=initial_delay, stop_on_exception=stop_on_exception)
|
||||||
|
|
|
@ -20,9 +20,6 @@ from oslotest import base as test_base
|
||||||
import oslo_service
|
import oslo_service
|
||||||
from oslo_service import loopingcall
|
from oslo_service import loopingcall
|
||||||
|
|
||||||
threading = eventlet.patcher.original('threading')
|
|
||||||
time = eventlet.patcher.original('time')
|
|
||||||
|
|
||||||
|
|
||||||
class LoopingCallTestCase(test_base.BaseTestCase):
|
class LoopingCallTestCase(test_base.BaseTestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue