-
Notifications
You must be signed in to change notification settings - Fork 0
/
fsnotify.go
100 lines (89 loc) · 1.92 KB
/
fsnotify.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package fsnotify
import (
"path/filepath"
"time"
"github.com/fsnotify/fsnotify"
"github.com/hopeio/cherry/utils/log"
)
type Watch struct {
*fsnotify.Watcher
interval time.Duration
done chan struct{}
handler map[string]Callback
}
type Callback struct {
lastModTime time.Time
callbacks []func()
}
type Handler map[string]Callback
func New(interval time.Duration) (*Watch, error) {
watcher, err := fsnotify.NewWatcher()
w := &Watch{
Watcher: watcher,
interval: interval,
done: make(chan struct{}, 1),
//1.map和数组做取舍
handler: make(map[string]Callback),
//Handler: make(map[string]map[fsnotify.Op]func()),
//2.提高时间复杂度,用event做key,然后每次事件循环取值
//Handler: make(map[fsnotify.Event]func()),
}
if err == nil {
go w.run()
}
return w, err
}
func (w *Watch) Add(name string, op fsnotify.Op, callback func()) error {
name = filepath.Clean(name)
handle, ok := w.handler[name]
if !ok {
err := w.Watcher.Add(name)
if err != nil {
return err
}
w.handler[name] = Callback{
callbacks: make([]func(), 5, 5),
}
handle = w.handler[name]
}
handle.callbacks[op-1] = callback
return nil
}
func (w *Watch) run() {
ev := &fsnotify.Event{}
OuterLoop:
for {
select {
case event, ok := <-w.Watcher.Events:
if !ok {
return
}
log.Info("event:", event)
ev = &event
if handle, ok := w.handler[event.Name]; ok {
now := time.Now()
if now.Sub(handle.lastModTime) < w.interval && event == *ev {
continue
}
handle.lastModTime = now
for i := range handle.callbacks {
if event.Op&fsnotify.Op(i+1) == fsnotify.Op(i+1) && handle.callbacks[i] != nil {
handle.callbacks[i]()
}
}
}
case err, ok := <-w.Watcher.Errors:
if !ok {
return
}
log.Error("error:", err)
case <-w.done:
break OuterLoop
}
}
}
func (w *Watch) Close() {
w.done <- struct{}{}
close(w.done)
w.Watcher.Close()
}