@@ -106,9 +106,42 @@ def __init__(
106106 for config_path in config_paths
107107 ]
108108 self ._output : Sender [abc .Mapping [str , Any ]] = output
109- self ._event_types : abc .Set [EventType ] = event_types
110- self ._force_polling : bool = force_polling
111- self ._polling_interval : timedelta = polling_interval
109+
110+ # FileWatcher instance should be create here instead of in _run().
111+ # Otherwise, if the actor restarts, we will lost all the events that happened
112+ # while the actor was down.
113+ self ._file_watcher = self ._create_file_watcher (
114+ force_polling , polling_interval , event_types
115+ )
116+
117+ def _create_file_watcher (
118+ self ,
119+ force_polling : bool ,
120+ polling_interval : timedelta ,
121+ event_types : abc .Set [EventType ],
122+ ) -> FileWatcher :
123+ """Create a FileWatcher instance to monitor the configuration files.
124+
125+ Args:
126+ force_polling: Whether to force file polling to check for changes.
127+ polling_interval: The interval to poll for changes. Only relevant if
128+ polling is enabled.
129+ event_types: The set of event types to monitor.
130+
131+ Returns:
132+ A FileWatcher instance.
133+ """
134+ parent_paths = {p .parent for p in self ._config_paths }
135+
136+ # FileWatcher can't watch for non-existing files, so we need to watch for the
137+ # parent directories instead just in case a configuration file doesn't exist yet
138+ # or it is deleted and recreated again.
139+ return FileWatcher (
140+ paths = list (parent_paths ),
141+ event_types = event_types ,
142+ force_polling = force_polling ,
143+ polling_interval = polling_interval ,
144+ )
112145
113146 def _read_config (self ) -> abc .Mapping [str , Any ]:
114147 """Read the contents of the configuration file.
@@ -156,51 +189,36 @@ async def _run(self) -> None:
156189 """
157190 await self .send_config ()
158191
159- parent_paths = {p .parent for p in self ._config_paths }
160-
161- # FileWatcher can't watch for non-existing files, so we need to watch for the
162- # parent directories instead just in case a configuration file doesn't exist yet
163- # or it is deleted and recreated again.
164- file_watcher = FileWatcher (
165- paths = list (parent_paths ),
166- event_types = self ._event_types ,
167- force_polling = self ._force_polling ,
168- polling_interval = self ._polling_interval ,
169- )
170-
171- try :
172- async for event in file_watcher :
173- # Since we are watching the whole parent directories, we need to make
174- # sure we only react to events related to the configuration files we
175- # are interested in.
176- if not any (event .path .samefile (p ) for p in self ._config_paths ):
177- continue
178-
179- match event .type :
180- case EventType .CREATE :
181- _logger .info (
182- "%s: The configuration file %s was created, sending new config..." ,
183- self ,
184- event .path ,
185- )
186- await self .send_config ()
187- case EventType .MODIFY :
188- _logger .info (
189- "%s: The configuration file %s was modified, sending update..." ,
190- self ,
191- event .path ,
192- )
193- await self .send_config ()
194- case EventType .DELETE :
195- _logger .info (
196- "%s: The configuration file %s was deleted, ignoring..." ,
197- self ,
198- event .path ,
199- )
200- case _:
201- assert_never (event .type )
202- finally :
203- del file_watcher
192+ async for event in self ._file_watcher :
193+ # Since we are watching the whole parent directories, we need to make
194+ # sure we only react to events related to the configuration files we
195+ # are interested in.
196+ if not any (event .path .samefile (p ) for p in self ._config_paths ):
197+ continue
198+
199+ match event .type :
200+ case EventType .CREATE :
201+ _logger .info (
202+ "%s: The configuration file %s was created, sending new config..." ,
203+ self ,
204+ event .path ,
205+ )
206+ await self .send_config ()
207+ case EventType .MODIFY :
208+ _logger .info (
209+ "%s: The configuration file %s was modified, sending update..." ,
210+ self ,
211+ event .path ,
212+ )
213+ await self .send_config ()
214+ case EventType .DELETE :
215+ _logger .info (
216+ "%s: The configuration file %s was deleted, ignoring..." ,
217+ self ,
218+ event .path ,
219+ )
220+ case _:
221+ assert_never (event .type )
204222
205223
206224def _recursive_update (
0 commit comments