Skip to content

Commit 1299db2

Browse files
Amend actor documentation (#883)
- [x] Update internal documentation for the actor method `_run_loop()` - [x] Check and amend actor documentation and examples Fixes #797
2 parents 2947dc5 + b102e50 commit 1299db2

File tree

2 files changed

+20
-17
lines changed

2 files changed

+20
-17
lines changed

src/frequenz/sdk/actor/__init__.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class communicates through message passing. Even when no particular message pass
7070
### The `run()` Function
7171
7272
The [`run()`][frequenz.sdk.actor.run] function can start many actors at once and waits
73-
for them to finish. If any of the actors are stopped with errors, the errors will be
73+
for them to finish. If any of the actors is stopped with errors, the errors will be
7474
logged.
7575
7676
???+ example
@@ -85,13 +85,13 @@ async def _run(self) -> None:
8585
await run(MyActor()) # (1)!
8686
```
8787
88-
1. This line will block until the actor is stopped.
88+
1. This line will block until the actor completes its execution or is manually stopped.
8989
9090
### Async Context Manager
9191
9292
When an actor is used as an [async context manager], it is started when the
9393
`async with` block is entered and stopped automatically when the block is exited
94-
(even if an exception is raised).
94+
(even if an unhandled exception is raised).
9595
9696
???+ example
9797
@@ -116,7 +116,7 @@ async def _run(self) -> None:
116116
117117
When using the [`start()`][frequenz.sdk.actor.Actor.start] method, the actor is
118118
started in the background and the method returns immediately. The actor will
119-
continue to run until it is **manually** stopped.
119+
continue to run until it is **manually** stopped or until it completes its execution.
120120
121121
???+ example
122122
@@ -203,8 +203,8 @@ def __init__(
203203
logs.
204204
5. We call [`Actor.__init__()`][frequenz.sdk.actor.Actor.__init__] to make sure the
205205
actor is properly initialized.
206-
6. We store the `input` argument in a *private* instance variable to use it later.
207-
7. We store the `output` argument in a *private* instance variable to use it later.
206+
6. We store the `input` argument in a *private* attribute to use it later.
207+
7. We store the `output` argument in a *private* attribute to use it later.
208208
209209
### The `_run()` Method
210210
@@ -216,6 +216,8 @@ def __init__(
216216
in the `_run()` method, typically receiving messages from one or more channels
217217
([receivers][frequenz.channels.Receiver]), processing them and sending the results to
218218
other channels ([senders][frequenz.channels.Sender]).
219+
However, it is worth noting that an actor can also be designed for a one-time execution
220+
or a limited number of runs, terminating upon completion.
219221
220222
???+ example "Example echo actor"
221223
@@ -383,7 +385,7 @@ async def main() -> None: # (2)!
383385
384386
async with ( # (5)!
385387
Actor1(input_channel.new_receiver(), middle_channel.new_sender(), "actor1"),
386-
Actor2(middle_channel.new_receiver(), output_channel.new_sender(), "actor1"),
388+
Actor2(middle_channel.new_receiver(), output_channel.new_sender(), "actor2"),
387389
):
388390
await input_sender.send("Hello") # (6)!
389391
msg = await output_receiver.receive() # (7)!
@@ -397,7 +399,7 @@ async def main() -> None: # (2)!
397399
1. We define 2 actors: `Actor1` and `Actor2` that will just forward a message
398400
from an input channel to an output channel, adding some text.
399401
400-
2. We define an async `main()` function with the main logic of our [asyncio][] program.
402+
2. We define an async `main()` function within the main logic of our [asyncio][] program.
401403
402404
3. We start the `main()` function in the async loop using [`asyncio.run()`][asyncio.run].
403405
@@ -525,8 +527,8 @@ async def main() -> None: # (6)!
525527
them to another channel.
526528
527529
2. We implement the [`_run()`][_run] method that will receive messages from the two
528-
channels using and send them to the output channel. The `run()` method will stop if
529-
a `False` message is received.
530+
channels using [`select()`][frequenz.channels.util.select] and send them to the
531+
output channel. The `run()` method will stop if a `False` message is received.
530532
531533
3. We create the channels that will be used with the actor.
532534
@@ -556,8 +558,7 @@ async def main() -> None: # (6)!
556558
message, so `"Received from receiver_1: True"` will be printed and `True` will be
557559
sent to the `output` channel.
558560
559-
12. Since `selected.value` is `True`, the loop will continue, going back to the and the
560-
the loop will continue, going back to the
561+
12. Since `selected.value` is `True`, the loop will continue, going back to the
561562
[`select()`][frequenz.channels.util.select] function.
562563
563564
13. The [`selected_from()`][frequenz.channels.util.selected_from] function will return

src/frequenz/sdk/actor/_actor.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ async def _delay_if_restart(self, iteration: int) -> None:
7373
await asyncio.sleep(delay)
7474

7575
async def _run_loop(self) -> None:
76-
"""Run this actor's task in a loop until `_restart_limit` is reached.
76+
"""Run the actor's task continuously, managing restarts, cancellation, and termination.
77+
78+
This method handles the execution of the actor's task, including
79+
restarts for unhandled exceptions, cancellation, or normal termination.
7780
7881
Raises:
79-
asyncio.CancelledError: If this actor's `_run()` gets cancelled.
80-
Exception: If this actor's `_run()` raises any other `Exception` and reached
81-
the maximum number of restarts.
82-
BaseException: If this actor's `_run()` raises any other `BaseException`.
82+
asyncio.CancelledError: If the actor's `_run()` method is cancelled.
83+
Exception: If the actor's `_run()` method raises any other exception.
84+
BaseException: If the actor's `_run()` method raises any base exception.
8385
"""
8486
_logger.info("Actor %s: Started.", self)
8587
n_restarts = 0

0 commit comments

Comments
 (0)