Skip to content

Commit 88b8efc

Browse files
Replace asyncio gather() with wait()
This will be only useful in the future if the actor decorator does no longer manage the lifecycle of the actor tasks. Logging the tasks done in this case might contain useful debugging information as they include cancellation information. Signed-off-by: Daniel Zullo <[email protected]>
1 parent 37d499e commit 88b8efc

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

src/frequenz/sdk/actor/_run_utils.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66

77
import asyncio
8+
import logging
89
from typing import Any
910

1011
from ._decorator import BaseActor
1112

13+
_logger = logging.getLogger(__name__)
14+
1215

1316
async def run(*actors: Any) -> None:
1417
"""Await the completion of all actors.
@@ -24,4 +27,27 @@ async def run(*actors: Any) -> None:
2427
for actor in actors:
2528
assert isinstance(actor, BaseActor), f"{actor} is not an instance of BaseActor"
2629

27-
await asyncio.gather(*(actor.join() for actor in actors))
30+
pending_tasks = set()
31+
for actor in actors:
32+
pending_tasks.add(asyncio.create_task(actor.join(), name=str(actor)))
33+
34+
# Currently the actor decorator manages the life-cycle of the actor tasks
35+
while pending_tasks:
36+
done_tasks, pending_tasks = await asyncio.wait(
37+
pending_tasks, return_when=asyncio.FIRST_COMPLETED
38+
)
39+
40+
# This should always be only one task, but we handle many for extra safety
41+
for task in done_tasks:
42+
# Cancellation needs to be checked first, otherwise the other methods
43+
# could raise a CancelledError
44+
if task.cancelled():
45+
_logger.info("The actor %s was cancelled", task.get_name())
46+
elif exception := task.exception():
47+
_logger.error(
48+
"The actor %s was finished due to an uncaught exception",
49+
task.get_name(),
50+
exc_info=exception,
51+
)
52+
else:
53+
_logger.info("The actor %s finished normally", task.get_name())

0 commit comments

Comments
 (0)