-
Notifications
You must be signed in to change notification settings - Fork 2
/
poll_watcher.go
71 lines (65 loc) · 1.66 KB
/
poll_watcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package file
import (
"github.com/configcat/configcat-proxy/config"
"github.com/configcat/configcat-proxy/log"
"github.com/configcat/configcat-proxy/sdk/store"
"os"
"path/filepath"
"time"
)
type pollWatcher struct {
store.Notifier
log log.Logger
poller *time.Ticker
realFilePath string
lastModifiedDate time.Time
lastSize int64
}
func newPollWatcher(conf *config.LocalConfig, log log.Logger) (*pollWatcher, error) {
fsLog := log.WithPrefix("poll-watcher")
stat, err := os.Stat(conf.FilePath)
if err != nil {
fsLog.Errorf("failed to start poll watch on %s: %s", conf.FilePath, err)
return nil, err
}
realPath, err := filepath.EvalSymlinks(conf.FilePath)
if err != nil {
fsLog.Errorf("failed to eval symlink for %s: %s", realPath, err)
return nil, err
}
p := &pollWatcher{
Notifier: store.NewNotifier(),
poller: time.NewTicker(time.Duration(conf.PollInterval) * time.Second),
log: fsLog,
realFilePath: realPath,
lastModifiedDate: stat.ModTime(),
lastSize: stat.Size(),
}
fsLog.Reportf("started watching %s", p.realFilePath)
go p.run()
return p, nil
}
func (p *pollWatcher) run() {
for {
select {
case <-p.poller.C:
stat, err := os.Stat(p.realFilePath)
if err != nil {
p.log.Errorf("failed to read stat on %s: %s", p.realFilePath, err)
continue
}
if stat.ModTime() != p.lastModifiedDate || stat.Size() != p.lastSize {
p.lastModifiedDate = stat.ModTime()
p.lastSize = stat.Size()
p.Notify()
}
case <-p.Closed():
return
}
}
}
func (p *pollWatcher) Close() {
p.Notifier.Close()
p.poller.Stop()
p.log.Reportf("shutdown complete")
}