Skip to content

Commit 4d384e5

Browse files
Fix ConfigManagingActor crashing when any file was deleted
`event.path.samefile` raises error if: * `event.pathq` doesn't exists * path `p` doesn't exists In this case it raised exception: * if any file in parent directory was deleted * any path in self._config_paths didn't exist Signed-off-by: Elzbieta Kotulska <[email protected]>
1 parent 916eaec commit 4d384e5

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

src/frequenz/sdk/config/_config_managing.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def __init__(
7474
self,
7575
config_paths: abc.Sequence[pathlib.Path | str],
7676
output: Sender[abc.Mapping[str, Any]],
77-
event_types: abc.Set[EventType] = frozenset(EventType),
7877
*,
7978
name: str | None = None,
8079
force_polling: bool = True,
@@ -89,7 +88,6 @@ def __init__(
8988
the previous paths. Dict keys will be merged recursively, but other
9089
objects (like lists) will be replaced by the value in the last path.
9190
output: The sender to send the configuration to.
92-
event_types: The set of event types to monitor.
9391
name: The name of the actor. If `None`, `str(id(self))` will
9492
be used. This is used mostly for debugging purposes.
9593
force_polling: Whether to force file polling to check for changes.
@@ -106,7 +104,6 @@ def __init__(
106104
for config_path in config_paths
107105
]
108106
self._output: Sender[abc.Mapping[str, Any]] = output
109-
self._event_types: abc.Set[EventType] = event_types
110107
self._force_polling: bool = force_polling
111108
self._polling_interval: timedelta = polling_interval
112109

@@ -166,17 +163,32 @@ async def _run(self) -> None:
166163
# or it is deleted and recreated again.
167164
file_watcher = FileWatcher(
168165
paths=list(parent_paths),
169-
event_types=self._event_types,
166+
event_types={EventType.CREATE, EventType.MODIFY},
170167
force_polling=self._force_polling,
171168
polling_interval=self._polling_interval,
172169
)
173170

174171
try:
175172
async for event in file_watcher:
173+
if not event.path.exists():
174+
_logger.error(
175+
"%s: Received event %s, but the watched path %s doesn't exist.",
176+
self,
177+
event,
178+
event.path,
179+
)
180+
continue
176181
# Since we are watching the whole parent directories, we need to make
177182
# sure we only react to events related to the configuration files we
178183
# are interested in.
179-
if not any(event.path.samefile(p) for p in self._config_paths):
184+
#
185+
# pathlib.Path.samefile raises error if any path doesn't exist so we need to
186+
# make sure the paths exists before calling it. This could happen as it is not
187+
# required that all config files exist, only one is required but we don't know
188+
# which.
189+
if not any(
190+
event.path.samefile(p) for p in self._config_paths if p.exists()
191+
):
180192
continue
181193

182194
match event.type:
@@ -195,8 +207,9 @@ async def _run(self) -> None:
195207
)
196208
await self.send_config()
197209
case EventType.DELETE:
198-
_logger.info(
199-
"%s: The configuration file %s was deleted, ignoring...",
210+
_logger.error(
211+
"%s: Unexpected DELETE event for path %s. Please report this "
212+
"issue to Frequenz.",
200213
self,
201214
event.path,
202215
)

0 commit comments

Comments
 (0)