diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-07 16:32:10 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-07 16:32:10 +0200 |
| commit | 3fd46f3977fb650974e5e936cba362c787c00637 (patch) | |
| tree | b49111ddd0b7af4a007bca6a304dba10efcd88ff /internal/watcher | |
reimport this PoC
Diffstat (limited to 'internal/watcher')
| -rw-r--r-- | internal/watcher/file_watcher.go | 86 |
1 files changed, 86 insertions, 0 deletions
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 +} |
