Skip to content

Commit 0f985e2

Browse files
committed
Remove actor decorator
Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 67a9c22 commit 0f985e2

File tree

4 files changed

+33
-263
lines changed

4 files changed

+33
-263
lines changed

src/frequenz/sdk/actor/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from ._channel_registry import ChannelRegistry
1010
from ._config_managing import ConfigManagingActor
1111
from ._data_sourcing import ComponentMetricRequest, DataSourcingActor
12-
from ._decorator import actor
1312
from ._resampling import ComponentMetricsResamplingActor
1413
from ._run_utils import run
1514

@@ -22,6 +21,5 @@
2221
"ConfigManagingActor",
2322
"DataSourcingActor",
2423
"ResamplerConfig",
25-
"actor",
2624
"run",
2725
]

src/frequenz/sdk/actor/_decorator.py

Lines changed: 0 additions & 234 deletions
This file was deleted.

src/frequenz/sdk/actor/_run_utils.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,39 @@
66

77
import asyncio
88
import logging
9-
from typing import Any
109

1110
from ._actor import Actor
12-
from ._decorator import BaseActor
1311

1412
_logger = logging.getLogger(__name__)
1513

1614

17-
async def run(*actors: Any) -> None:
15+
async def run(*actors: Actor) -> None:
1816
"""Await the completion of all actors.
1917
2018
Args:
2119
actors: the actors to be awaited.
22-
23-
Raises:
24-
AssertionError: if any of the actors is not an instance of BaseActor.
2520
"""
26-
pending_tasks: set[asyncio.Task[Any]] = set()
27-
28-
# Check that each actor is an instance of BaseActor or Actor at runtime,
29-
# due to the indirection created by the actor decorator.
30-
for actor in actors:
31-
if isinstance(actor, Actor):
32-
await actor.start()
33-
awaitable = actor.wait()
34-
else:
35-
assert isinstance(
36-
actor, BaseActor
37-
), f"{actor} is not an instance of BaseActor or Actor"
38-
awaitable = actor.join() # type: ignore
39-
pending_tasks.add(asyncio.create_task(awaitable, name=str(actor)))
40-
41-
# Currently the actor decorator manages the life-cycle of the actor tasks
21+
_logger.info("Starting %s actor(s)...", len(actors))
22+
await _wait_tasks(
23+
set(asyncio.create_task(a.start(), name=str(a)) for a in actors),
24+
"starting",
25+
"started",
26+
)
27+
28+
# Wait until all actors are done
29+
await _wait_tasks(
30+
set(asyncio.create_task(a.wait(), name=str(a)) for a in actors),
31+
"running",
32+
"finished",
33+
)
34+
35+
_logger.info("All %s actor(s) finished.", len(actors))
36+
37+
38+
async def _wait_tasks(
39+
tasks: set[asyncio.Task[None]], error_str: str, success_str: str
40+
) -> None:
41+
pending_tasks = tasks
4242
while pending_tasks:
4343
done_tasks, pending_tasks = await asyncio.wait(
4444
pending_tasks, return_when=asyncio.FIRST_COMPLETED
@@ -49,12 +49,19 @@ async def run(*actors: Any) -> None:
4949
# Cancellation needs to be checked first, otherwise the other methods
5050
# could raise a CancelledError
5151
if task.cancelled():
52-
_logger.info("The actor %s was cancelled", task.get_name())
52+
_logger.info(
53+
"Actor %s: Cancelled while %s.",
54+
task.get_name(),
55+
error_str,
56+
)
5357
elif exception := task.exception():
5458
_logger.error(
55-
"The actor %s was finished due to an uncaught exception",
59+
"Actor %s: Raised an exception while %s.",
5660
task.get_name(),
61+
error_str,
5762
exc_info=exception,
5863
)
5964
else:
60-
_logger.info("The actor %s finished normally", task.get_name())
65+
_logger.info(
66+
"Actor %s: %s normally.", task.get_name(), success_str.capitalize()
67+
)

tests/conftest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""Setup for all the tests."""
55
import pytest
66

7-
from frequenz.sdk.actor import _actor, _decorator
7+
from frequenz.sdk.actor import _actor
88

99
# Used to impose a hard time limit for some async tasks in tests so that tests don't
1010
# run forever in case of a bug
@@ -23,5 +23,4 @@ def disable_actor_auto_restart(): # type: ignore
2323
Note: Test class must derive after unittest.IsolatedAsyncioTestCase.
2424
Otherwise this fixture won't run.
2525
"""
26-
_decorator.BaseActor.restart_limit = 0
2726
_actor.Actor._restart_limit = 0 # pylint: disable=protected-access

0 commit comments

Comments
 (0)