|
22 | 22 | """The logger for this module.""" |
23 | 23 |
|
24 | 24 |
|
| 25 | +# pylint: disable=too-many-instance-attributes |
25 | 26 | class DispatchingActor(Actor): |
26 | 27 | """Dispatch actor. |
27 | 28 |
|
@@ -84,12 +85,14 @@ def __init__( |
84 | 85 | always at index 0. |
85 | 86 | """ |
86 | 87 |
|
| 88 | + self._currently_fetching = False |
| 89 | + |
87 | 90 | async def _run(self) -> None: |
88 | 91 | """Run the actor.""" |
89 | 92 | _logger.info("Starting dispatch actor for microgrid %s", self._microgrid_id) |
90 | 93 |
|
91 | 94 | # Initial fetch |
92 | | - await self._fetch() |
| 95 | + await self.fetch() |
93 | 96 |
|
94 | 97 | stream = self._client.stream(microgrid_id=self._microgrid_id) |
95 | 98 |
|
@@ -151,52 +154,58 @@ async def _execute_scheduled_event(self, dispatch: Dispatch) -> None: |
151 | 154 |
|
152 | 155 | self._update_timer() |
153 | 156 |
|
154 | | - async def _fetch(self) -> None: |
| 157 | + async def fetch(self) -> None: |
155 | 158 | """Fetch all relevant dispatches using list. |
156 | 159 |
|
157 | 160 | This is used for the initial fetch and for re-fetching all dispatches |
158 | 161 | if the connection was lost. |
159 | 162 | """ |
160 | | - old_dispatches = self._dispatches |
161 | | - self._dispatches = {} |
162 | | - |
163 | | - try: |
164 | | - _logger.info("Fetching dispatches for microgrid %s", self._microgrid_id) |
165 | | - async for page in self._client.list(microgrid_id=self._microgrid_id): |
166 | | - for client_dispatch in page: |
167 | | - dispatch = Dispatch(client_dispatch) |
168 | | - |
169 | | - self._dispatches[dispatch.id] = Dispatch(client_dispatch) |
170 | | - old_dispatch = old_dispatches.pop(dispatch.id, None) |
171 | | - if not old_dispatch: |
172 | | - _logger.info("New dispatch: %s", dispatch) |
173 | | - await self._update_dispatch_schedule_and_notify(dispatch, None) |
174 | | - await self._lifecycle_updates_sender.send( |
175 | | - Created(dispatch=dispatch) |
176 | | - ) |
177 | | - elif dispatch.update_time != old_dispatch.update_time: |
178 | | - _logger.info("Updated dispatch: %s", dispatch) |
179 | | - await self._update_dispatch_schedule_and_notify( |
180 | | - dispatch, old_dispatch |
181 | | - ) |
182 | | - await self._lifecycle_updates_sender.send( |
183 | | - Updated(dispatch=dispatch) |
184 | | - ) |
185 | | - |
186 | | - except grpc.aio.AioRpcError as error: |
187 | | - _logger.error("Error fetching dispatches: %s", error) |
188 | | - self._dispatches = old_dispatches |
| 163 | + if self._currently_fetching: |
| 164 | + _logger.debug("Already fetching dispatches, skipping") |
189 | 165 | return |
190 | 166 |
|
191 | | - for dispatch in old_dispatches.values(): |
192 | | - _logger.info("Deleted dispatch: %s", dispatch) |
193 | | - await self._lifecycle_updates_sender.send(Deleted(dispatch=dispatch)) |
194 | | - await self._update_dispatch_schedule_and_notify(None, dispatch) |
195 | | - |
196 | | - # Set deleted only here as it influences the result of dispatch.started |
197 | | - # which is used in above in _running_state_change |
198 | | - dispatch._set_deleted() # pylint: disable=protected-access |
199 | | - await self._lifecycle_updates_sender.send(Deleted(dispatch=dispatch)) |
| 167 | + try: |
| 168 | + self._currently_fetching = True |
| 169 | + |
| 170 | + old_dispatches = self._dispatches |
| 171 | + self._dispatches = {} |
| 172 | + |
| 173 | + try: |
| 174 | + _logger.info("Fetching dispatches for microgrid %s", self._microgrid_id) |
| 175 | + async for page in self._client.list(microgrid_id=self._microgrid_id): |
| 176 | + for client_dispatch in page: |
| 177 | + dispatch = Dispatch(client_dispatch) |
| 178 | + |
| 179 | + self._dispatches[dispatch.id] = Dispatch(client_dispatch) |
| 180 | + old_dispatch = old_dispatches.pop(dispatch.id, None) |
| 181 | + if not old_dispatch: |
| 182 | + _logger.info("New dispatch: %s", dispatch) |
| 183 | + await self._update_dispatch_schedule_and_notify( |
| 184 | + dispatch, None |
| 185 | + ) |
| 186 | + await self._lifecycle_updates_sender.send( |
| 187 | + Created(dispatch=dispatch) |
| 188 | + ) |
| 189 | + elif dispatch.update_time != old_dispatch.update_time: |
| 190 | + _logger.info("Updated dispatch: %s", dispatch) |
| 191 | + await self._update_dispatch_schedule_and_notify( |
| 192 | + dispatch, old_dispatch |
| 193 | + ) |
| 194 | + await self._lifecycle_updates_sender.send( |
| 195 | + Updated(dispatch=dispatch) |
| 196 | + ) |
| 197 | + |
| 198 | + except grpc.aio.AioRpcError as error: |
| 199 | + _logger.error("Error fetching dispatches: %s", error) |
| 200 | + self._dispatches = old_dispatches |
| 201 | + return |
| 202 | + |
| 203 | + for dispatch in old_dispatches.values(): |
| 204 | + _logger.info("Deleted dispatch: %s", dispatch) |
| 205 | + await self._update_dispatch_schedule_and_notify(None, dispatch) |
| 206 | + await self._lifecycle_updates_sender.send(Deleted(dispatch=dispatch)) |
| 207 | + finally: |
| 208 | + self._currently_fetching = False |
200 | 209 |
|
201 | 210 | async def _update_dispatch_schedule_and_notify( |
202 | 211 | self, dispatch: Dispatch | None, old_dispatch: Dispatch | None |
|
0 commit comments