Skip to content

Commit 99cf1dd

Browse files
authored
Merge pull request #31 from JuBiotech/async-events
WIP: Use async events to facilitate async command implementation
2 parents 5c6607d + a2caa4e commit 99cf1dd

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

‎cri_lib/cri_controller.py‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ class MotionType(Enum):
3333
Platform = "Platform"
3434

3535

36+
async def wait_event_with_timeout(event: asyncio.Event, timeout: float):
37+
t_start = time()
38+
while not event.is_set():
39+
await asyncio.sleep(0.001)
40+
if time() - t_start > timeout:
41+
raise TimeoutError
42+
return
43+
44+
3645
class CRIClient:
3746
"""Client with implementations for read-only communication."""
3847

@@ -69,7 +78,7 @@ def __init__(self) -> None:
6978
self.sent_command_counter_lock = threading.Lock()
7079
self.sent_command_counter = 0
7180
self.answer_events_lock = threading.Lock()
72-
self.answer_events: dict[str, threading.Event] = {}
81+
self.answer_events: dict[str, asyncio.Event] = {}
7382
self.error_messages: dict[str, str] = {}
7483

7584
self.status_callback: Callable | None = None
@@ -160,7 +169,7 @@ def close(self) -> None:
160169

161170
def _register_answer(self, answer_id: str) -> None:
162171
with self.answer_events_lock:
163-
self.answer_events[answer_id] = threading.Event()
172+
self.answer_events[answer_id] = asyncio.Event()
164173

165174
def _send_command(
166175
self,
@@ -206,9 +215,9 @@ def _send_command(
206215
if register_answer:
207216
with self.answer_events_lock:
208217
if fixed_answer_name is not None:
209-
self.answer_events[fixed_answer_name] = threading.Event()
218+
self.answer_events[fixed_answer_name] = asyncio.Event()
210219
else:
211-
self.answer_events[str(command_counter)] = threading.Event()
220+
self.answer_events[str(command_counter)] = asyncio.Event()
212221

213222
try:
214223
with self.socket_write_lock:
@@ -287,6 +296,14 @@ def _wait_for_answer(
287296
self,
288297
message_id: str | int,
289298
timeout: float | None = DEFAULT, # type: ignore
299+
) -> None | str:
300+
loop = asyncio.get_event_loop()
301+
return loop.run_until_complete(self._wait_for_answer_async(message_id, timeout))
302+
303+
async def _wait_for_answer_async(
304+
self,
305+
message_id: str | int,
306+
timeout: float | None = DEFAULT, # type: ignore
290307
) -> None | str:
291308
"""Waits for an answer to a message.
292309
The answer event will be removed after the call, even if there was a timeout. Choose timeout accordingly.
@@ -319,9 +336,9 @@ def _wait_for_answer(
319336
return None
320337
wait_event = self.answer_events[message_id]
321338

322-
if timeout is DEFAULT:
339+
if timeout is DEFAULT or timeout is None:
323340
timeout = self.DEFAULT_ANSWER_TIMEOUT
324-
success = wait_event.wait(timeout=timeout)
341+
success = await wait_event_with_timeout(wait_event, timeout=timeout)
325342

326343
if not success:
327344
raise CRICommandTimeOutError()

0 commit comments

Comments
 (0)