@@ -242,7 +242,7 @@ func configFilesWatcher(
242242 // needed for lastContents and lastIncludes because they get updated in multiple goroutines
243243 mu := sync.Mutex {}
244244
245- checkForContentChangesBeforeCallback := func () {
245+ parseAndCompareBeforeCallback := func () {
246246 currentContents , currentIncludes , err := parseYAMLIncludes (mainFilePath )
247247 if err != nil {
248248 onErr (fmt .Errorf ("parsing main file contents for comparison: %w" , err ))
@@ -268,15 +268,22 @@ func configFilesWatcher(
268268
269269 const debounceDuration = 500 * time .Millisecond
270270 var debounceTimer * time.Timer
271- debouncedCallback := func () {
271+ debouncedParseAndCompareBeforeCallback := func () {
272272 if debounceTimer != nil {
273273 debounceTimer .Stop ()
274274 debounceTimer .Reset (debounceDuration )
275275 } else {
276- debounceTimer = time .AfterFunc (debounceDuration , checkForContentChangesBeforeCallback )
276+ debounceTimer = time .AfterFunc (debounceDuration , parseAndCompareBeforeCallback )
277277 }
278278 }
279279
280+ deleteLastInclude := func (filePath string ) {
281+ mu .Lock ()
282+ defer mu .Unlock ()
283+ fileAbsPath , _ := filepath .Abs (filePath )
284+ delete (lastIncludes , fileAbsPath )
285+ }
286+
280287 go func () {
281288 for {
282289 select {
@@ -285,33 +292,33 @@ func configFilesWatcher(
285292 return
286293 }
287294 if event .Has (fsnotify .Write ) {
288- debouncedCallback ()
295+ debouncedParseAndCompareBeforeCallback ()
289296 } else if event .Has (fsnotify .Rename ) {
290- // wait for file to be available
291- for i := 0 ; i < 20 ; i ++ {
292- _ , err := os .Stat (mainFileAbsPath )
293- if err == nil {
297+ // on linux the file will no longer be watched after a rename, on windows
298+ // it will continue to be watched with the new name but we have no access to
299+ // the new name in this event in order to stop watching it manually and match the
300+ // behavior in linux, may lead to weird unintended behaviors on windows as we're
301+ // only handling renames from linux's perspective
302+ // see https://github.com/fsnotify/fsnotify/issues/255
303+
304+ // remove the old file from our manually tracked includes, calling
305+ // debouncedParseAndCompareBeforeCallback will re-add it if it's still
306+ // required after it triggers
307+ deleteLastInclude (event .Name )
308+
309+ // wait for file to maybe get created again
310+ // see https://github.com/glanceapp/glance/pull/358
311+ for i := 0 ; i < 10 ; i ++ {
312+ if _ , err := os .Stat (event .Name ); err == nil {
294313 break
295314 }
296- time .Sleep (100 * time .Millisecond )
297- }
298- // fsnotify removes the file from the watch list on rename events,
299- // add it back.
300- // See https://github.com/fsnotify/fsnotify/issues/214
301- err := watcher .Add (mainFileAbsPath )
302- if err != nil {
303- onErr (fmt .Errorf ("watching file:" , err ))
315+ time .Sleep (200 * time .Millisecond )
304316 }
305- debouncedCallback ()
317+
318+ debouncedParseAndCompareBeforeCallback ()
306319 } else if event .Has (fsnotify .Remove ) {
307- func () {
308- mu .Lock ()
309- defer mu .Unlock ()
310- fileAbsPath , _ := filepath .Abs (event .Name )
311- delete (lastIncludes , fileAbsPath )
312- }()
313-
314- debouncedCallback ()
320+ deleteLastInclude (event .Name )
321+ debouncedParseAndCompareBeforeCallback ()
315322 }
316323 case err , isOpen := <- watcher .Errors :
317324 if ! isOpen {
0 commit comments