Skip to content

Commit 4cfd024

Browse files
committed
Update Docs, Readme, Release Notes
Signed-off-by: Mathias L. Baumann <[email protected]>
1 parent 763331c commit 4cfd024

File tree

4 files changed

+118
-39
lines changed

4 files changed

+118
-39
lines changed

README.md

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@ The [`Dispatcher` class](https://frequenz-floss.github.io/frequenz-dispatch-pyth
2121

2222
```python
2323
import os
24-
from frequenz.dispatch import Dispatcher
2524
from unittest.mock import MagicMock
25+
from datetime import timedelta
26+
27+
from frequenz.dispatch import Dispatcher, DispatchInfo, MergeByType
28+
29+
async def create_actor(dispatch: DispatchInfo, receiver: Receiver[DispatchInfo]) -> Actor:
30+
return MagicMock(dispatch=dispatch, receiver=receiver)
2631

2732
async def run():
2833
url = os.getenv("DISPATCH_API_URL", "grpc://fz-0004.frequenz.io:50051")
@@ -33,35 +38,19 @@ async def run():
3338
dispatcher = Dispatcher(
3439
microgrid_id=microgrid_id,
3540
server_url=url,
36-
key=key
41+
key=key,
42+
autostart=True
43+
)
44+
45+
dispatcher.start_dispatching(
46+
dispatch_type="EXAMPLE_TYPE",
47+
actor_factory=create_actor,
48+
merge_strategy=MergeByType(),
49+
retry_interval=timedelta(seconds=10)
3750
)
38-
await dispatcher.start()
39-
40-
actor = MagicMock() # replace with your actor
41-
42-
changed_running_status_rx = dispatcher.new_running_state_event_receiver("MY_TYPE")
43-
44-
async for dispatch in changed_running_status_rx:
45-
if dispatch.started:
46-
print(f"Executing dispatch {dispatch.id}, due on {dispatch.start_time}")
47-
if actor.is_running:
48-
actor.reconfigure(
49-
components=dispatch.target,
50-
run_parameters=dispatch.payload, # custom actor parameters
51-
dry_run=dispatch.dry_run,
52-
until=dispatch.until,
53-
) # this will reconfigure the actor
54-
else:
55-
# this will start a new actor with the given components
56-
# and run it for the duration of the dispatch
57-
actor.start(
58-
components=dispatch.target,
59-
run_parameters=dispatch.payload, # custom actor parameters
60-
dry_run=dispatch.dry_run,
61-
until=dispatch.until,
62-
)
63-
else:
64-
actor.stop() # this will stop the actor
51+
52+
await dispatcher
53+
6554
```
6655

6756
## Supported Platforms

RELEASE_NOTES.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,47 @@ This release introduces a more flexible and powerful mechanism for managing disp
66

77
## Upgrading
88

9+
A new simplified way to manage actors has been introduced:
10+
11+
Change your code from:
12+
```python
13+
dispatcher = Dispatcher(
14+
microgrid_id=microgrid_id,
15+
server_url=url,
16+
key=key
17+
)
18+
dispatcher.start()
19+
20+
status_receiver = dispatcher.new_running_state_event_receiver("EXAMPLE_TYPE")
21+
22+
managing_actor = ActorDispatcher(
23+
actor_factory=MyActor.new_with_dispatch,
24+
running_status_receiver=status_receiver,
25+
)
26+
27+
await run(managing_actor)
28+
```
29+
30+
to
31+
32+
```python
33+
dispatcher = Dispatcher(
34+
microgrid_id=microgrid_id,
35+
server_url=url,
36+
key=key,
37+
autostart=True
38+
)
39+
40+
dispatcher.start_dispatching(
41+
dispatch_type="EXAMPLE_TYPE",
42+
actor_factory=MyActor.new_with_dispatch,
43+
merge_strategy=MergeStrategy.MergeByType,
44+
retry_interval=10
45+
)
46+
```
47+
48+
Further changes:
49+
950
* `Dispatcher.__init__` has a new optional parameter `autostart`, which defaults to `True`. If set to `False`, the dispatcher will not start automatically.
1051
* `Dispatcher.start` is no longer `async`. Remove `await` when calling it.
1152
* Two properties have been replaced by methods that require a type as parameter.

src/frequenz/dispatch/_actor_dispatcher.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ async def main():
122122
dispatcher = Dispatcher(
123123
microgrid_id=microgrid_id,
124124
server_url=url,
125-
key=key
125+
key=key,
126+
autostart=True
126127
)
127-
dispatcher.start()
128128
129129
status_receiver = dispatcher.new_running_state_event_receiver("EXAMPLE_TYPE")
130130

src/frequenz/dispatch/_dispatcher.py

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ class Dispatcher(BackgroundService):
2828
"""A highlevel interface for the dispatch API.
2929
3030
This class provides a highlevel interface to the dispatch API.
31-
It provides two receiver functions:
31+
It provides receivers for various events and management of actors based on
32+
dispatches.
33+
34+
The receivers shortly explained:
3235
3336
* [Lifecycle events receiver][frequenz.dispatch.Dispatcher.new_lifecycle_events_receiver]:
3437
Receives an event whenever a dispatch is created, updated or deleted.
@@ -42,6 +45,38 @@ class Dispatcher(BackgroundService):
4245
Any change that could potentially require the consumer to start, stop or
4346
reconfigure itself will cause a message to be sent.
4447
48+
Example: Managing an actor
49+
```python
50+
import os
51+
from frequenz.dispatch import Dispatcher, MergeByType
52+
from unittest.mock import MagicMock
53+
54+
async def create_actor(dispatch: DispatchInfo, receiver: Receiver[DispatchInfo]) -> Actor:
55+
return MagicMock(dispatch=dispatch, receiver=receiver)
56+
57+
async def run():
58+
url = os.getenv("DISPATCH_API_URL", "grpc://fz-0004.frequenz.io:50051")
59+
key = os.getenv("DISPATCH_API_KEY", "some-key")
60+
61+
microgrid_id = 1
62+
63+
dispatcher = Dispatcher(
64+
microgrid_id=microgrid_id,
65+
server_url=url,
66+
key=key,
67+
autostart=True
68+
)
69+
70+
dispatcher.start_dispatching(
71+
dispatch_type="DISPATCH_TYPE",
72+
actor_factory=create_actor,
73+
merge_strategy=MergeByType(),
74+
retry_interval=timedelta(seconds=60),
75+
)
76+
77+
await dispatcher
78+
```
79+
4580
Example: Processing running state change dispatches
4681
```python
4782
import os
@@ -57,9 +92,9 @@ async def run():
5792
dispatcher = Dispatcher(
5893
microgrid_id=microgrid_id,
5994
server_url=url,
60-
key=key
95+
key=key,
96+
autostart=True
6197
)
62-
await dispatcher.start()
6398
6499
actor = MagicMock() # replace with your actor
65100
@@ -104,9 +139,9 @@ async def run():
104139
dispatcher = Dispatcher(
105140
microgrid_id=microgrid_id,
106141
server_url=url,
107-
key=key
142+
key=key,
143+
autostart=True
108144
)
109-
await dispatcher.start() # this will start the actor
110145
111146
events_receiver = dispatcher.new_lifecycle_events_receiver("DISPATCH_TYPE")
112147
@@ -142,9 +177,9 @@ async def run():
142177
dispatcher = Dispatcher(
143178
microgrid_id=microgrid_id,
144179
server_url=url,
145-
key=key
180+
key=key,
181+
autostart=True
146182
)
147-
await dispatcher.start() # this will start the actor
148183
149184
# Create a new dispatch
150185
new_dispatch = await dispatcher.client.create(
@@ -250,13 +285,27 @@ async def start_dispatching(
250285
) -> None:
251286
"""Manage actors for a given dispatch type.
252287
253-
Creates and manages an ActorDispatcher for the given type that will
288+
Creates and manages an
289+
[`ActorDispatcher`][frequenz.dispatch.ActorDispatcher] for the given type that will
254290
start, stop and reconfigure actors based on received dispatches.
255291
256292
You can await the `Dispatcher` instance to block until all types
257293
registered with `start_dispatching()` are stopped using
258294
`stop_dispatching()`
259295
296+
"Merging" means that when multiple dispatches are active at the same time,
297+
the intervals are merged into one.
298+
299+
This also decides how instances are mapped from dispatches to actors:
300+
301+
* [`MergeByType`][frequenz.dispatch.MergeByType] — All dispatches map to
302+
one single instance identified by the dispatch type.
303+
* [`MergeByTypeTarget`][frequenz.dispatch.MergeByTypeTarget] — A
304+
dispatch maps to an instance identified by the dispatch type and target.
305+
So different dispatches with equal type and target will map to the same
306+
instance.
307+
* `None` — No merging, each dispatch maps to a separate instance.
308+
260309
Args:
261310
dispatch_type: The type of the dispatch to manage.
262311
actor_factory: The factory to create actors.

0 commit comments

Comments
 (0)