Skip to content

Commit 9f4681e

Browse files
Create FileWatcher when ConfigManagingActor runs (#1074)
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.
2 parents 2d4e119 + 90f0c60 commit 9f4681e

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)