Add threading<->eventlet compatible Event

This creates an object that is backed by either a threading or
eventlet Event, depending on whether eventlet is available.  In the
eventlet case, the object wraps the eventlet.event.Event object to
provide an API that matches that of threading.Event.  This allows the
user to be ignorant of which implementation is backing the object and
to use both interchangeably.

Change-Id: Id33c9f8c17102ba1fe24c12b053c336b6d265501
Related-Bug: #1518430
This commit is contained in:
John Eckersberg 2016-10-21 10:40:53 -04:00
parent 69bf513b00
commit d0cd71c1fc
2 changed files with 55 additions and 0 deletions

View File

@ -138,3 +138,38 @@ def is_monkey_patched(module):
if _patcher is None:
return False
return _patcher.is_monkey_patched(module)
class _Event(object):
"""A class that provides consistent eventlet/threading Event API.
This wraps the eventlet.event.Event class to have the same API as
the standard threading.Event object.
"""
def __init__(self, *args, **kwargs):
self.clear()
def clear(self):
self._set = False
self._event = _eventlet.event.Event()
def is_set(self):
return self._set
isSet = is_set
def set(self):
self._set = True
self._event.send(True)
def wait(self, timeout=None):
with _eventlet.timeout.Timeout(timeout, False):
self._event.wait()
return self.is_set()
def Event():
if EVENTLET_AVAILABLE:
return _Event()
else:
return threading.Event()

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import threading
import warnings
import mock
@ -121,3 +122,22 @@ class EventletUtilsTest(test_base.BaseTestCase):
self.assertRaises(ValueError,
eventletutils.warn_eventlet_not_patched,
['blah.blah'])
@mock.patch('oslo_utils.eventletutils._Event.clear')
def test_event_api_compat(self, mock_clear):
e_event = eventletutils.Event()
self.assertIsInstance(e_event, eventletutils._Event)
eventletutils.EVENTLET_AVAILABLE = False
t_event = eventletutils.Event()
if six.PY3:
t_event_cls = threading.Event
else:
t_event_cls = threading._Event
self.assertIsInstance(t_event, t_event_cls)
public_methods = [m for m in dir(t_event) if not m.startswith("_") and
callable(getattr(t_event, m))]
for method in public_methods:
self.assertTrue(hasattr(e_event, method))