X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;f=eventlet%2Feventlet%2Fevent.py;fp=eventlet%2Feventlet%2Fevent.py;h=0000000000000000000000000000000000000000;hb=358bd9258c2b6d2ee74de4dfd07a5123107abad4;hp=f06e0069269d96f640ae12a7a86402f0887c6a69;hpb=376ff3bfe7071cc0793184a378c4e74508fb0d97;p=packages%2Ftrusty%2Fpython-eventlet.git diff --git a/eventlet/eventlet/event.py b/eventlet/eventlet/event.py deleted file mode 100644 index f06e006..0000000 --- a/eventlet/eventlet/event.py +++ /dev/null @@ -1,213 +0,0 @@ -from __future__ import print_function - -from eventlet import hubs -from eventlet.support import greenlets as greenlet - -__all__ = ['Event'] - - -class NOT_USED: - def __repr__(self): - return 'NOT_USED' - -NOT_USED = NOT_USED() - - -class Event(object): - """An abstraction where an arbitrary number of coroutines - can wait for one event from another. - - Events are similar to a Queue that can only hold one item, but differ - in two important ways: - - 1. calling :meth:`send` never unschedules the current greenthread - 2. :meth:`send` can only be called once; create a new event to send again. - - They are good for communicating results between coroutines, and - are the basis for how - :meth:`GreenThread.wait() ` - is implemented. - - >>> from eventlet import event - >>> import eventlet - >>> evt = event.Event() - >>> def baz(b): - ... evt.send(b + 1) - ... - >>> _ = eventlet.spawn_n(baz, 3) - >>> evt.wait() - 4 - """ - _result = None - _exc = None - - def __init__(self): - self._waiters = set() - self.reset() - - def __str__(self): - params = (self.__class__.__name__, hex(id(self)), - self._result, self._exc, len(self._waiters)) - return '<%s at %s result=%r _exc=%r _waiters[%d]>' % params - - def reset(self): - # this is kind of a misfeature and doesn't work perfectly well, - # it's better to create a new event rather than reset an old one - # removing documentation so that we don't get new use cases for it - assert self._result is not NOT_USED, 'Trying to re-reset() a fresh event.' - self._result = NOT_USED - self._exc = None - - def ready(self): - """ Return true if the :meth:`wait` call will return immediately. - Used to avoid waiting for things that might take a while to time out. - For example, you can put a bunch of events into a list, and then visit - them all repeatedly, calling :meth:`ready` until one returns ``True``, - and then you can :meth:`wait` on that one.""" - return self._result is not NOT_USED - - def has_exception(self): - return self._exc is not None - - def has_result(self): - return self._result is not NOT_USED and self._exc is None - - def poll(self, notready=None): - if self.ready(): - return self.wait() - return notready - - # QQQ make it return tuple (type, value, tb) instead of raising - # because - # 1) "poll" does not imply raising - # 2) it's better not to screw up caller's sys.exc_info() by default - # (e.g. if caller wants to calls the function in except or finally) - def poll_exception(self, notready=None): - if self.has_exception(): - return self.wait() - return notready - - def poll_result(self, notready=None): - if self.has_result(): - return self.wait() - return notready - - def wait(self): - """Wait until another coroutine calls :meth:`send`. - Returns the value the other coroutine passed to - :meth:`send`. - - >>> from eventlet import event - >>> import eventlet - >>> evt = event.Event() - >>> def wait_on(): - ... retval = evt.wait() - ... print("waited for {0}".format(retval)) - >>> _ = eventlet.spawn(wait_on) - >>> evt.send('result') - >>> eventlet.sleep(0) - waited for result - - Returns immediately if the event has already - occured. - - >>> evt.wait() - 'result' - """ - current = greenlet.getcurrent() - if self._result is NOT_USED: - self._waiters.add(current) - try: - return hubs.get_hub().switch() - finally: - self._waiters.discard(current) - if self._exc is not None: - current.throw(*self._exc) - return self._result - - def send(self, result=None, exc=None): - """Makes arrangements for the waiters to be woken with the - result and then returns immediately to the parent. - - >>> from eventlet import event - >>> import eventlet - >>> evt = event.Event() - >>> def waiter(): - ... print('about to wait') - ... result = evt.wait() - ... print('waited for {0}'.format(result)) - >>> _ = eventlet.spawn(waiter) - >>> eventlet.sleep(0) - about to wait - >>> evt.send('a') - >>> eventlet.sleep(0) - waited for a - - It is an error to call :meth:`send` multiple times on the same event. - - >>> evt.send('whoops') - Traceback (most recent call last): - ... - AssertionError: Trying to re-send() an already-triggered event. - - Use :meth:`reset` between :meth:`send` s to reuse an event object. - """ - assert self._result is NOT_USED, 'Trying to re-send() an already-triggered event.' - self._result = result - if exc is not None and not isinstance(exc, tuple): - exc = (exc, ) - self._exc = exc - hub = hubs.get_hub() - for waiter in self._waiters: - hub.schedule_call_global( - 0, self._do_send, self._result, self._exc, waiter) - - def _do_send(self, result, exc, waiter): - if waiter in self._waiters: - if exc is None: - waiter.switch(result) - else: - waiter.throw(*exc) - - def send_exception(self, *args): - """Same as :meth:`send`, but sends an exception to waiters. - - The arguments to send_exception are the same as the arguments - to ``raise``. If a single exception object is passed in, it - will be re-raised when :meth:`wait` is called, generating a - new stacktrace. - - >>> from eventlet import event - >>> evt = event.Event() - >>> evt.send_exception(RuntimeError()) - >>> evt.wait() - Traceback (most recent call last): - File "", line 1, in - File "eventlet/event.py", line 120, in wait - current.throw(*self._exc) - RuntimeError - - If it's important to preserve the entire original stack trace, - you must pass in the entire :func:`sys.exc_info` tuple. - - >>> import sys - >>> evt = event.Event() - >>> try: - ... raise RuntimeError() - ... except RuntimeError: - ... evt.send_exception(*sys.exc_info()) - ... - >>> evt.wait() - Traceback (most recent call last): - File "", line 1, in - File "eventlet/event.py", line 120, in wait - current.throw(*self._exc) - File "", line 2, in - RuntimeError - - Note that doing so stores a traceback object directly on the - Event object, which may cause reference cycles. See the - :func:`sys.exc_info` documentation. - """ - # the arguments and the same as for greenlet.throw - return self.send(None, args)