utils.py 956 B

123456789101112131415161718192021222324252627282930313233343536
  1. import trio
  2. __all__ = ["race_events"]
  3. # Based on https://trio.readthedocs.io/en/stable/reference-core.html#custom-supervisors
  4. async def jockey(event: trio.Event, cancel_scope: trio.CancelScope) -> None:
  5. await event.wait()
  6. cancel_scope.cancel()
  7. async def race_events(*events: trio.Event) -> None:
  8. """
  9. Wait for any of the given events to be set.
  10. Args:
  11. *events: The events to wait for.
  12. """
  13. if not events:
  14. raise ValueError("no events provided")
  15. try:
  16. async with trio.open_nursery() as nursery:
  17. for event in events:
  18. nursery.start_soon(jockey, event, nursery.cancel_scope)
  19. except BaseExceptionGroup as exc:
  20. try:
  21. trio._util.raise_single_exception_from_group(exc)
  22. except trio._util.MultipleExceptionError:
  23. raise AssertionError(
  24. "race_events should be canceled; please file a bug report"
  25. ) from exc