Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@

- The `actor.ChannelRegistry` is now type-aware.

- The error messages when `BackgroundService` implementations don't call `super().__init__()` have been improved.

## Bug Fixes

- 0W power requests are now not adjusted to exclusion bounds by the `PowerManager` and `PowerDistributor`, and are sent over to the microgrid API directly.
Expand Down
14 changes: 14 additions & 0 deletions src/frequenz/sdk/actor/_background_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def name(self) -> str:
Returns:
The name of this background service.
"""
self._assert_initialized()
return self._name

@property
Expand All @@ -107,6 +108,7 @@ def tasks(self) -> collections.abc.Set[asyncio.Task[Any]]:
Returns:
The set of running tasks spawned by this background service.
"""
self._assert_initialized()
return self._tasks

@property
Expand All @@ -118,6 +120,7 @@ def is_running(self) -> bool:
Returns:
Whether this background service is running.
"""
self._assert_initialized()
return any(not task.done() for task in self._tasks)

def cancel(self, msg: str | None = None) -> None:
Expand All @@ -126,6 +129,7 @@ def cancel(self, msg: str | None = None) -> None:
Args:
msg: The message to be passed to the tasks being cancelled.
"""
self._assert_initialized()
for task in self._tasks:
task.cancel(msg)

Expand All @@ -144,6 +148,7 @@ async def stop(self, msg: str | None = None) -> None:

[//]: # (# noqa: DAR401 rest)
"""
self._assert_initialized()
if not self._tasks:
return
self.cancel(msg)
Expand All @@ -166,6 +171,7 @@ async def __aenter__(self) -> Self:
Returns:
This background service.
"""
self._assert_initialized()
self.start()
return self

Expand Down Expand Up @@ -196,6 +202,7 @@ async def wait(self) -> None:
exception (`CancelError` is not considered an error and not returned in
the exception group).
"""
self._assert_initialized()
# We need to account for tasks that were created between when we started
# awaiting and we finished awaiting.
while self._tasks:
Expand Down Expand Up @@ -251,3 +258,10 @@ def __str__(self) -> str:
A string representation of this instance.
"""
return f"{type(self).__name__}[{self._name}]"

def _assert_initialized(self) -> None:
"""Assert this instance is initialized."""
assert hasattr(self, "_tasks"), (
f"{type(self).__name__} instance is not initialized. "
"Make sure to call `super().__init__()` in your __init__() method."
)