Browse code

Select polling based watcher for Windows log watcher

Signed-off-by: Tejaswini Duggaraju <naduggar@microsoft.com>

Tejaswini Duggaraju authored on 2018/07/07 07:48:59
Showing 1 changed files
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"fmt"
9 9
 	"io"
10 10
 	"os"
11
+	"runtime"
11 12
 	"strconv"
12 13
 	"strings"
13 14
 	"sync"
... ...
@@ -641,9 +642,20 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
641 641
 }
642 642
 
643 643
 func watchFile(name string) (filenotify.FileWatcher, error) {
644
-	fileWatcher, err := filenotify.New()
645
-	if err != nil {
646
-		return nil, err
644
+	var fileWatcher filenotify.FileWatcher
645
+
646
+	if runtime.GOOS == "windows" {
647
+		// FileWatcher on Windows files is based on the syscall notifications which has an issue becuase of file caching.
648
+		// It is based on ReadDirectoryChangesW() which doesn't detect writes to the cache. It detects writes to disk only.
649
+		// Becuase of the OS lazy writing, we don't get notifications for file writes and thereby the watcher
650
+		// doesn't work. Hence for Windows we will use poll based notifier.
651
+		fileWatcher = filenotify.NewPollingWatcher()
652
+	} else {
653
+		var err error
654
+		fileWatcher, err = filenotify.New()
655
+		if err != nil {
656
+			return nil, err
657
+		}
647 658
 	}
648 659
 
649 660
 	logger := logrus.WithFields(logrus.Fields{
... ...
@@ -652,6 +664,7 @@ func watchFile(name string) (filenotify.FileWatcher, error) {
652 652
 	})
653 653
 
654 654
 	if err := fileWatcher.Add(name); err != nil {
655
+		// we will retry using file poller.
655 656
 		logger.WithError(err).Warnf("falling back to file poller")
656 657
 		fileWatcher.Close()
657 658
 		fileWatcher = filenotify.NewPollingWatcher()
... ...
@@ -662,5 +675,6 @@ func watchFile(name string) (filenotify.FileWatcher, error) {
662 662
 			return nil, err
663 663
 		}
664 664
 	}
665
+
665 666
 	return fileWatcher, nil
666 667
 }