# `event` – Cross-greenthread primitive

class eventlet.event.Event

  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 `send()` never unschedules the current greenthread

  2. `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 `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

  ready()

    Return true if the `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 `ready()` until one returns `True`, and then you can `wait()` on that one.

  send(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 `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 `reset()` between `send()` s to reuse an event object.

  send_exception(*args)

    Same as `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 `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 "<stdin>", line 1, in <module>
          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 `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 "<stdin>", line 1, in <module>
          File "eventlet/event.py", line 120, in wait
            current.throw(*self._exc)
          File "<stdin>", line 2, in <module>
        RuntimeError

    Note that doing so stores a traceback object directly on the Event object, which may cause reference cycles. See the `sys.exc_info()` documentation.

  wait(timeout=None)

    Wait until another coroutine calls `send()`. Returns the value the other coroutine passed to `send()`.

        >>> import eventlet
        >>> evt = eventlet.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 occurred.

        >>> evt.wait()
        'result'

    When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof).