diff --git a/oslo_service/loopingcall.py b/oslo_service/loopingcall.py index 74438914..9e6a8799 100644 --- a/oslo_service/loopingcall.py +++ b/oslo_service/loopingcall.py @@ -17,13 +17,12 @@ import random import sys -import threading import time from eventlet import event from eventlet import greenthread +from eventlet import timeout as eventlettimeout from oslo_log import log as logging -from oslo_utils import eventletutils from oslo_utils import excutils from oslo_utils import reflection from oslo_utils import timeutils @@ -77,51 +76,30 @@ def _safe_wrapper(f, kind, func_name): return func -def _Event(): - if eventletutils.is_monkey_patched('thread'): - return _ThreadingEvent() - else: - return _GreenEvent() +class _Event(object): + """A class that provides consistent eventlet/threading Event API. - -class _ThreadingEvent(object): - def __init__(self): - self._abort = threading.Event() - - def is_running(self): - return not self._abort.is_set() + It's a copy from the oslo_utils repository, as we need the private version + because we don't want to use the threading.Event version. + """ + def __init__(self, *args, **kwargs): + self.clear() def clear(self): - self._abort.clear() + self._set = False + self._event = event.Event() - def wait(self, timeout): - self._abort.wait(timeout) + def is_set(self): + return self._set - def stop(self): - self._abort.set() + def set(self): + self._set = True + self._event.send(True) - def done(self): - pass - - -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 + def wait(self, timeout=None): + with eventlettimeout.Timeout(timeout, False): + self._event.wait() + return self.is_set() class LoopingCallBase(object): @@ -136,24 +114,23 @@ class LoopingCallBase(object): self.f = f self._thread = None self.done = None - self._event = _Event() + self._abort = _Event() @property def _running(self): - return self._event.is_running() + return not self._abort.is_set() def stop(self): - self._event.stop() + self._abort.set() def wait(self): return self.done.wait() def _on_done(self, gt, *args, **kwargs): self._thread = None - self._event.done() def _sleep(self, timeout): - self._event.wait(timeout) + self._abort.wait(timeout) def _start(self, idle_for, initial_delay=None, stop_on_exception=True): """Start the looping @@ -171,7 +148,7 @@ class LoopingCallBase(object): if self._thread is not None: raise RuntimeError(self._RUN_ONLY_ONE_MESSAGE) self.done = event.Event() - self._event.clear() + self._abort.clear() self._thread = greenthread.spawn( self._run_loop, idle_for, initial_delay=initial_delay, stop_on_exception=stop_on_exception) diff --git a/oslo_service/tests/test_loopingcall.py b/oslo_service/tests/test_loopingcall.py index 54402fea..9ca0afe2 100644 --- a/oslo_service/tests/test_loopingcall.py +++ b/oslo_service/tests/test_loopingcall.py @@ -20,9 +20,6 @@ from oslotest import base as test_base import oslo_service from oslo_service import loopingcall -threading = eventlet.patcher.original('threading') -time = eventlet.patcher.original('time') - class LoopingCallTestCase(test_base.BaseTestCase):