Skip to content

Commit 90f0c60

Browse files
Create FileWatcher when ConfigManagingActor runs
The ConfigManagingActor was unable to process events after being restarted because the FileWatcher cannot be reused when the ConfigManagingActor is restarted, so we need to create a new instance every time the actor starts running. Signed-off-by: Daniel Zullo <[email protected]>
1 parent 2d4e119 commit 90f0c60

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414

1515
## Bug Fixes
1616

17-
<!-- Here goes notable bug fixes that are worth a special mention or explanation -->
17+
- `ConfigManagingActor`: Fixed an issue where the actor was unable to process events after being restarted.

src/frequenz/sdk/config/_config_managing.py

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,8 @@ def __init__(
5252
if isinstance(config_path, pathlib.Path)
5353
else pathlib.Path(config_path)
5454
)
55-
# FileWatcher can't watch for non-existing files, so we need to watch for the
56-
# parent directory instead just in case a configuration file doesn't exist yet
57-
# or it is deleted and recreated again.
58-
self._file_watcher: FileWatcher = FileWatcher(
59-
paths=[self._config_path.parent], event_types=event_types
60-
)
6155
self._output: Sender[abc.Mapping[str, Any]] = output
56+
self._event_types: abc.Set[EventType] = event_types
6257

6358
def _read_config(self) -> abc.Mapping[str, Any]:
6459
"""Read the contents of the configuration file.
@@ -90,32 +85,42 @@ async def _run(self) -> None:
9085
"""
9186
await self.send_config()
9287

93-
async for event in self._file_watcher:
94-
# Since we are watching the whole parent directory, we need to make sure
95-
# we only react to events related to the configuration file.
96-
if not event.path.samefile(self._config_path):
97-
continue
98-
99-
match event.type:
100-
case EventType.CREATE:
101-
_logger.info(
102-
"%s: The configuration file %s was created, sending new config...",
103-
self,
104-
self._config_path,
105-
)
106-
await self.send_config()
107-
case EventType.MODIFY:
108-
_logger.info(
109-
"%s: The configuration file %s was modified, sending update...",
110-
self,
111-
self._config_path,
112-
)
113-
await self.send_config()
114-
case EventType.DELETE:
115-
_logger.info(
116-
"%s: The configuration file %s was deleted, ignoring...",
117-
self,
118-
self._config_path,
119-
)
120-
case _:
121-
assert_never(event.type)
88+
# FileWatcher can't watch for non-existing files, so we need to watch for the
89+
# parent directory instead just in case a configuration file doesn't exist yet
90+
# or it is deleted and recreated again.
91+
file_watcher = FileWatcher(
92+
paths=[self._config_path.parent], event_types=self._event_types
93+
)
94+
95+
try:
96+
async for event in file_watcher:
97+
# Since we are watching the whole parent directory, we need to make sure
98+
# we only react to events related to the configuration file.
99+
if not event.path.samefile(self._config_path):
100+
continue
101+
102+
match event.type:
103+
case EventType.CREATE:
104+
_logger.info(
105+
"%s: The configuration file %s was created, sending new config...",
106+
self,
107+
self._config_path,
108+
)
109+
await self.send_config()
110+
case EventType.MODIFY:
111+
_logger.info(
112+
"%s: The configuration file %s was modified, sending update...",
113+
self,
114+
self._config_path,
115+
)
116+
await self.send_config()
117+
case EventType.DELETE:
118+
_logger.info(
119+
"%s: The configuration file %s was deleted, ignoring...",
120+
self,
121+
self._config_path,
122+
)
123+
case _:
124+
assert_never(event.type)
125+
finally:
126+
del file_watcher

0 commit comments

Comments
 (0)