mirror of https://github.com/docker/compose.git
watch: a new strategy for handling spurious events, hoping to fix race conditions (#163)
This commit is contained in:
parent
4801d2b1a4
commit
4562b0bf95
|
@ -134,6 +134,9 @@ func TestWatchNonExistentPath(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f.fsync()
|
||||
|
||||
d1 := []byte("hello\ngo\n")
|
||||
err = ioutil.WriteFile(path, d1, 0644)
|
||||
if err != nil {
|
||||
|
|
|
@ -20,21 +20,13 @@ type darwinNotify struct {
|
|||
// so that, for recursive watches, we can guarantee that the path list doesn't
|
||||
// change.
|
||||
sm *sync.Mutex
|
||||
}
|
||||
|
||||
func (d *darwinNotify) isTrackingPath(path string) bool {
|
||||
d.sm.Lock()
|
||||
defer d.sm.Unlock()
|
||||
for _, p := range d.stream.Paths {
|
||||
if p == path {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
// ignore the first event that says the watched directory
|
||||
// has been created. these are fired spuriously on initiation.
|
||||
ignoreCreatedEvents map[string]bool
|
||||
}
|
||||
|
||||
func (d *darwinNotify) loop() {
|
||||
ignoredSpuriousEvents := make(map[string]bool, 0)
|
||||
for {
|
||||
select {
|
||||
case <-d.stop:
|
||||
|
@ -47,11 +39,20 @@ func (d *darwinNotify) loop() {
|
|||
for _, e := range events {
|
||||
e.Path = filepath.Join("/", e.Path)
|
||||
|
||||
// ignore the first event that says the watched directory
|
||||
// has been created. these are fired spuriously on initiation.
|
||||
if e.Flags&fsevents.ItemCreated == fsevents.ItemCreated {
|
||||
if !ignoredSpuriousEvents[e.Path] && d.isTrackingPath(e.Path) {
|
||||
ignoredSpuriousEvents[e.Path] = true
|
||||
d.sm.Lock()
|
||||
shouldIgnore := d.ignoreCreatedEvents[e.Path]
|
||||
if shouldIgnore {
|
||||
d.ignoreCreatedEvents[e.Path] = false
|
||||
} else {
|
||||
// If we got a created event for something
|
||||
// that's not on the ignore list, we assume
|
||||
// we're done with the spurious events.
|
||||
d.ignoreCreatedEvents = nil
|
||||
}
|
||||
d.sm.Unlock()
|
||||
|
||||
if shouldIgnore {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +81,12 @@ func (d *darwinNotify) Add(name string) error {
|
|||
}
|
||||
|
||||
es.Paths = append(es.Paths, name)
|
||||
|
||||
if d.ignoreCreatedEvents == nil {
|
||||
d.ignoreCreatedEvents = make(map[string]bool, 1)
|
||||
}
|
||||
d.ignoreCreatedEvents[name] = true
|
||||
|
||||
if len(es.Paths) == 1 {
|
||||
go d.loop()
|
||||
es.Start()
|
||||
|
|
Loading…
Reference in New Issue