Skip to content

Commit a71e5ba

Browse files
committed
Add utility to wait for several events.
Indeed, trio has no equivalent of asyncio.wait.
1 parent 7dde750 commit a71e5ba

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/websockets/trio/utils.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import trio
2+
3+
4+
__all__ = ["wait_for_any_event"]
5+
6+
7+
# Based on https://trio.readthedocs.io/en/stable/reference-core.html#custom-supervisors
8+
9+
10+
async def jockey(event: trio.Event, cancel_scope: trio.CancelScope) -> None:
11+
await event.wait()
12+
cancel_scope.cancel()
13+
14+
15+
async def wait_for_any_event(*events: trio.Event) -> None:
16+
"""
17+
Wait for any of the given events to be set.
18+
19+
Args:
20+
*events: The events to wait for.
21+
22+
"""
23+
if not events:
24+
raise ValueError("no events provided")
25+
26+
async with trio.open_nursery() as nursery:
27+
for event in events:
28+
nursery.start_soon(jockey, event, nursery.cancel_scope)

tests/trio/test_utils.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import trio.testing
2+
3+
from websockets.trio.utils import *
4+
5+
from .utils import IsolatedTrioTestCase
6+
7+
8+
class UtilsTests(IsolatedTrioTestCase):
9+
async def test_wait_for_any_event(self):
10+
event1 = trio.Event()
11+
event2 = trio.Event()
12+
done = trio.Event()
13+
14+
async def waiter():
15+
await wait_for_any_event(event1, event2)
16+
done.set()
17+
18+
self.nursery.start_soon(waiter)
19+
await trio.testing.wait_all_tasks_blocked()
20+
self.assertFalse(done.is_set())
21+
22+
event1.set()
23+
await trio.testing.wait_all_tasks_blocked()
24+
self.assertTrue(done.is_set())
25+
26+
async def test_wait_for_any_event_no_events(self):
27+
with self.assertRaises(ValueError):
28+
await wait_for_any_event()

0 commit comments

Comments
 (0)