Skip to content

Commit 6ac3334

Browse files
authored
Attempt to fix ci-gets-stuck in shutdown loop (#1237)
In an attempt to find the dependency that causes the CI to get stuck (the _max test works so it must be a min dependency)
2 parents 7a26a31 + fe92e6a commit 6ac3334

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

src/frequenz/sdk/_internal/_asyncio.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,22 @@ async def run_forever(
4646
while True:
4747
try:
4848
await async_callable()
49+
except RuntimeError as exc:
50+
if "no running event loop" in str(exc):
51+
_logger.exception(
52+
"Something went wrong, no running event loop, skipping execution of %s",
53+
async_callable.__name__,
54+
)
55+
return
4956
except Exception: # pylint: disable=broad-except
57+
if not asyncio.get_event_loop().is_running():
58+
_logger.exception(
59+
"Something went wrong, no running event loop, skipping execution of %s",
60+
async_callable.__name__,
61+
)
62+
return
5063
_logger.exception("Restarting after exception")
51-
await asyncio.sleep(interval_s)
64+
await asyncio.sleep(interval_s)
5265

5366

5467
class NotSyncConstructible(AssertionError):

src/frequenz/sdk/microgrid/_power_distributing/_component_pool_status_tracker.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66

77
import asyncio
88
import contextlib
9-
import logging
109
from collections import abc
1110
from datetime import timedelta
1211

1312
from frequenz.channels import Broadcast, Merger, Receiver, Sender, merge
1413
from frequenz.client.common.microgrid.components import ComponentId
1514

16-
from ..._internal._asyncio import cancel_and_await
15+
from ..._internal._asyncio import cancel_and_await, run_forever
1716
from ._component_status import (
1817
ComponentPoolStatus,
1918
ComponentStatus,
@@ -22,8 +21,6 @@
2221
SetPowerResult,
2322
)
2423

25-
_logger = logging.getLogger(__name__)
26-
2724

2825
class ComponentPoolStatusTracker:
2926
"""Track status of components of a given category.
@@ -112,14 +109,7 @@ async def _run(self) -> None:
112109
async with contextlib.AsyncExitStack() as stack:
113110
for tracker in self._component_status_trackers:
114111
await stack.enter_async_context(tracker)
115-
while True:
116-
try:
117-
await self._update_status()
118-
except Exception as err: # pylint: disable=broad-except
119-
_logger.error(
120-
"ComponentPoolStatus failed with error: %s. Restarting.", err
121-
)
122-
await asyncio.sleep(1.0)
112+
await run_forever(self._update_status)
123113

124114
async def _update_status(self) -> None:
125115
async for status in self._merged_status_receiver:

tests/microgrid/power_distributing/_component_status/test_battery_pool_status.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""Tests for BatteryPoolStatus."""
44

55
import asyncio
6+
from contextlib import AsyncExitStack
67
from datetime import timedelta
78

89
from frequenz.channels import Broadcast
@@ -37,7 +38,8 @@ async def test_batteries_status(self, mocker: MockerFixture) -> None:
3738
mock_microgrid = MockMicrogrid(grid_meter=True, mocker=mocker)
3839
mock_microgrid.add_batteries(3)
3940

40-
async with mock_microgrid:
41+
async with AsyncExitStack() as stack:
42+
await stack.enter_async_context(mock_microgrid)
4143
batteries = {
4244
battery.component_id
4345
for battery in mock_microgrid.mock_client.component_graph.components(
@@ -55,6 +57,7 @@ async def test_batteries_status(self, mocker: MockerFixture) -> None:
5557
max_blocking_duration=timedelta(seconds=30),
5658
component_status_tracker_type=BatteryStatusTracker,
5759
)
60+
stack.push_async_callback(batteries_status.stop)
5861
await asyncio.sleep(0.1)
5962

6063
expected_working: set[ComponentId] = set()
@@ -123,5 +126,3 @@ async def test_batteries_status(self, mocker: MockerFixture) -> None:
123126
ComponentId(9),
124127
ComponentId(19),
125128
}
126-
127-
await batteries_status.stop()

tests/timeseries/mock_microgrid.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import asyncio
99
from collections.abc import Callable
1010
from datetime import datetime, timedelta, timezone
11+
from types import TracebackType
1112
from typing import Coroutine
1213

1314
from frequenz.client.common.microgrid.components import ComponentId
@@ -622,6 +623,12 @@ async def __aenter__(self) -> MockMicrogrid:
622623
await self.start()
623624
return self
624625

625-
async def __aexit__(self, exc_type: None, exc_val: None, exc_tb: None) -> None:
626+
async def __aexit__(
627+
self,
628+
exc_type: type[BaseException] | None,
629+
exc_value: BaseException | None,
630+
traceback: TracebackType | None,
631+
/,
632+
) -> None:
626633
"""Exit context manager."""
627634
await self.cleanup()

0 commit comments

Comments
 (0)