Avoid double-setting event

In commit cc8b51e1e1 we added a send
on the old event when clearing an EventletEvent. However, this was
done unconditionally, which means if the event was already sent
then we attempt to send it again. This fails with:

AssertionError: Trying to re-send() an already-triggered event.

Similar to 14a53c4d8a, we should check
if self._set is True and if so then we know that the event was
already sent and we don't need to do it again.

Change-Id: I660601383072d11e4a077aada8c1b8c30b9d8d1d
Closes-Bug: 1812922
This commit is contained in:
Ben Nemec 2019-01-23 15:13:12 +00:00
parent eff0629790
commit 4eb61941f8
2 changed files with 13 additions and 1 deletions

View File

@ -150,13 +150,15 @@ class EventletEvent(object):
"""
def __init__(self, *args, **kwargs):
super(EventletEvent, self).__init__()
self._set = False
self.clear()
def clear(self):
old_event = getattr(self, "_event", None)
was_set = self._set
self._set = False
self._event = _eventlet.event.Event()
if old_event is not None:
if old_event is not None and not was_set:
old_event.send(True)
def is_set(self):

View File

@ -200,3 +200,13 @@ class EventletUtilsTest(test_base.BaseTestCase):
b = greenthread.spawn(thread_b)
with eventlet.timeout.Timeout(0.7):
b.wait()
@mock.patch('oslo_utils.eventletutils._eventlet.event.Event')
def test_event_clear_already_sent(self, mock_event):
old_event = mock.Mock()
new_event = mock.Mock()
mock_event.side_effect = [old_event, new_event]
event = eventletutils.EventletEvent()
event.set()
event.clear()
self.assertEqual(1, old_event.send.call_count)