Skip to content

Commit 27af040

Browse files
committed
Tweak impl for handling config renames
1 parent 76a80ff commit 27af040

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

internal/glance/config.go

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)