From 3fd46f3977fb650974e5e936cba362c787c00637 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 7 Feb 2026 16:32:10 +0200 Subject: reimport this PoC --- internal/watcher/file_watcher.go | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 internal/watcher/file_watcher.go (limited to 'internal/watcher') diff --git a/internal/watcher/file_watcher.go b/internal/watcher/file_watcher.go new file mode 100644 index 0000000..63ccb08 --- /dev/null +++ b/internal/watcher/file_watcher.go @@ -0,0 +1,86 @@ +package watcher + +import ( + "context" + "fmt" + "os" + "time" +) + +// FileWatcher monitors a file for changes based on modification time. +type FileWatcher struct { + filePath string + pollInterval time.Duration + lastModTime time.Time +} + +// NewFileWatcher creates a new file watcher. +func NewFileWatcher(filePath string, pollInterval time.Duration) *FileWatcher { + return &FileWatcher{ + filePath: filePath, + pollInterval: pollInterval, + } +} + +// Watch starts watching the file and returns a channel that signals changes. +// If the file doesn't exist yet, it will wait until it appears. +func (fw *FileWatcher) Watch(ctx context.Context) (<-chan struct{}, error) { + changeChan := make(chan struct{}, 1) + + go func() { + defer close(changeChan) + ticker := time.NewTicker(fw.pollInterval) + defer ticker.Stop() + + fileExists := false + + // Wait for file to exist + for !fileExists { + select { + case <-ctx.Done(): + return + case <-ticker.C: + info, err := os.Stat(fw.filePath) + if err != nil { + // File doesn't exist yet, keep waiting + fmt.Printf("Waiting for file to exist: %s\n", fw.filePath) + continue + } + + // File now exists! + fileExists = true + fw.lastModTime = info.ModTime() + // Send initial change to process file + changeChan <- struct{}{} + fmt.Printf("File detected, starting watch: %s\n", fw.filePath) + } + } + + // Now watch for changes + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + info, err := os.Stat(fw.filePath) + if err != nil { + // File might have been deleted or is temporarily unavailable + continue + } + + modTime := info.ModTime() + if modTime.After(fw.lastModTime) { + fw.lastModTime = modTime + changeChan <- struct{}{} + } + } + } + }() + + return changeChan, nil +} + +// GetLastModTime returns the last known modification time of the file. +func (fw *FileWatcher) GetLastModTime() time.Time { + return fw.lastModTime +} -- cgit v1.2.3