@@ -41,7 +41,7 @@ class ActorDispatcher(BackgroundService):
4141 import os
4242 import asyncio
4343 from typing import override
44- from frequenz.dispatch import Dispatcher, DispatchManagingActor , DispatchInfo
44+ from frequenz.dispatch import Dispatcher, ActorDispatcher , DispatchInfo
4545 from frequenz.client.dispatch.types import TargetComponents
4646 from frequenz.client.common.microgrid.components import ComponentCategory
4747 from frequenz.channels import Receiver, Broadcast, select, selected_from
@@ -125,9 +125,10 @@ async def main():
125125
126126 status_receiver = dispatcher.new_running_state_event_receiver("EXAMPLE_TYPE")
127127
128- managing_actor = DispatchManagingActor (
128+ managing_actor = ActorDispatcher (
129129 actor_factory=MyActor.new_with_dispatch,
130130 running_status_receiver=status_receiver,
131+ map_dispatch=lambda dispatch: dispatch.id,
131132 )
132133
133134 await run(managing_actor)
@@ -138,18 +139,21 @@ def __init__(
138139 self ,
139140 actor_factory : Callable [[DispatchInfo , Receiver [DispatchInfo ]], Actor ],
140141 running_status_receiver : Receiver [Dispatch ],
142+ map_dispatch : Callable [[Dispatch ], int ],
141143 ) -> None :
142144 """Initialize the dispatch handler.
143145
144146 Args:
145147 actor_factory: A callable that creates an actor with some initial dispatch
146148 information.
147149 running_status_receiver: The receiver for dispatch running status changes.
150+ map_dispatch: A function to identify to which actor a dispatch refers.
148151 """
149152 super ().__init__ ()
153+ self ._map_dispatch = map_dispatch
150154 self ._dispatch_rx = running_status_receiver
151155 self ._actor_factory = actor_factory
152- self ._actor : Actor | None = None
156+ self ._actors : dict [ int , Actor ] = {}
153157 self ._updates_channel = Broadcast [DispatchInfo ](
154158 name = "dispatch_updates_channel" , resend_latest = True
155159 )
@@ -167,7 +171,9 @@ async def _start_actor(self, dispatch: Dispatch) -> None:
167171 options = dispatch .payload ,
168172 )
169173
170- if self ._actor :
174+ actor : Actor | None = self ._actors .get (self ._map_dispatch (dispatch ))
175+
176+ if actor :
171177 sent_str = ""
172178 if self ._updates_sender is not None :
173179 sent_str = ", sent a dispatch update instead of creating a new actor"
@@ -179,10 +185,12 @@ async def _start_actor(self, dispatch: Dispatch) -> None:
179185 )
180186 else :
181187 _logger .info ("Starting actor for dispatch type %r" , dispatch .type )
182- self . _actor = self ._actor_factory (
188+ actor = self ._actor_factory (
183189 dispatch_update , self ._updates_channel .new_receiver ()
184190 )
185- self ._actor .start ()
191+ self ._actors [self ._map_dispatch (dispatch )] = actor
192+
193+ actor .start ()
186194
187195 async def _stop_actor (self , stopping_dispatch : Dispatch , msg : str ) -> None :
188196 """Stop all actors.
@@ -191,13 +199,12 @@ async def _stop_actor(self, stopping_dispatch: Dispatch, msg: str) -> None:
191199 stopping_dispatch: The dispatch that is stopping the actor.
192200 msg: The message to be passed to the actors being stopped.
193201 """
194- if self ._actor is None :
202+ if actor := self ._actors .pop (self ._map_dispatch (stopping_dispatch ), None ):
203+ await actor .stop (msg )
204+ else :
195205 _logger .warning (
196206 "Actor for dispatch type %r is not running" , stopping_dispatch .type
197207 )
198- else :
199- await self ._actor .stop (msg )
200- self ._actor = None
201208
202209 async def _run (self ) -> None :
203210 """Wait for dispatches and handle them."""
0 commit comments