Skip to content

Commit d8655e3

Browse files
Fix ConfigManagingActor to handle missing config files gracefully
Eliminate recursive actor crashes when config files are missing. The previous implementation suffered from a critical error pattern: - The `_read_config` method is called at the start of the `_run` method and on FileWatcher event. - When no config files existed, an exception would be raised - This exception caused the actor to crash and immediately restart - Restarting triggered the same `_read_config` method - The cycle repeated, creating a persistent crash loop This fix introduces a more robust approach: - Detect missing config files without throwing exceptions - Set up a FileWatcher to monitor for future config file creation - call `_read_config` method as soon as any config file is crated. Signed-off-by: Elzbieta Kotulska <[email protected]>
1 parent 003ac25 commit d8655e3

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

src/frequenz/sdk/config/_config_managing.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,11 @@ def __init__(
107107
self._force_polling: bool = force_polling
108108
self._polling_interval: timedelta = polling_interval
109109

110-
def _read_config(self) -> abc.Mapping[str, Any]:
110+
def _read_config(self) -> abc.Mapping[str, Any] | None:
111111
"""Read the contents of the configuration file.
112112
113113
Returns:
114114
A dictionary containing configuration variables.
115-
116-
Raises:
117-
ValueError: If config file cannot be read.
118115
"""
119116
error_count = 0
120117
config: dict[str, Any] = {}
@@ -138,14 +135,18 @@ def _read_config(self) -> abc.Mapping[str, Any]:
138135
error_count += 1
139136

140137
if error_count == len(self._config_paths):
141-
raise ValueError(f"{self}: Can't read any of the config files")
138+
_logger.error(
139+
"%s: Can't read any of the config files, ignoring config update.", self
140+
)
141+
return None
142142

143143
return config
144144

145145
async def send_config(self) -> None:
146146
"""Send the configuration to the output sender."""
147147
config = self._read_config()
148-
await self._output.send(config)
148+
if config is not None:
149+
await self._output.send(config)
149150

150151
async def _run(self) -> None:
151152
"""Monitor for and send configuration file updates.

0 commit comments

Comments
 (0)