You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

38 lines
946 B

4 years ago
  1. import asyncio
  2. import collections
  3. class EventResultOrError:
  4. """
  5. This class wrappers the Event asyncio lock allowing either awake the
  6. locked Tasks without any error or raising an exception.
  7. thanks to @vorpalsmith for the simple design.
  8. """
  9. def __init__(self, loop):
  10. self._loop = loop
  11. self._exc = None
  12. self._event = asyncio.Event(loop=loop)
  13. self._waiters = collections.deque()
  14. def set(self, exc=None):
  15. self._exc = exc
  16. self._event.set()
  17. async def wait(self):
  18. waiter = self._loop.create_task(self._event.wait())
  19. self._waiters.append(waiter)
  20. try:
  21. val = await waiter
  22. finally:
  23. self._waiters.remove(waiter)
  24. if self._exc is not None:
  25. raise self._exc
  26. return val
  27. def cancel(self):
  28. """ Cancel all waiters """
  29. for waiter in self._waiters:
  30. waiter.cancel()