fixes on top of Florian's truncation detection (1ff299bc2)

* initialize `Size` with the then-size of the file when ChangeEvents
  is called. remember that this function is expected to be called many
  times, one after another. this also passes the TestReSeekInotify
  test.

* do not ignore errors from os.Stat. we panic errors like these now,
  but ideally should switch to tomb.Tomb for letting the user handle
  them.
This commit is contained in:
Sridhar Ratnakumar 2013-05-28 12:31:46 -07:00
parent 8c443fb067
commit 5ccafcc3d6
1 changed files with 13 additions and 2 deletions

View File

@ -8,6 +8,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"sync" "sync"
// "fmt"
) )
// FileWatcher monitors file-level events. // FileWatcher monitors file-level events.
@ -45,6 +46,7 @@ func (fw *InotifyFileWatcher) BlockUntilExists() error {
defer w.RemoveWatch(filepath.Dir(fw.Filename)) defer w.RemoveWatch(filepath.Dir(fw.Filename))
for { for {
evt := <-w.Event evt := <-w.Event
// fmt.Printf("block until exits (inotify) evt: %v\n", evt)
if evt.Name == fw.Filename { if evt.Name == fw.Filename {
break break
} }
@ -53,7 +55,7 @@ func (fw *InotifyFileWatcher) BlockUntilExists() error {
} }
// ChangeEvents returns a channel that gets updated when the file is ready to be read. // ChangeEvents returns a channel that gets updated when the file is ready to be read.
func (fw *InotifyFileWatcher) ChangeEvents(_ os.FileInfo) chan bool { func (fw *InotifyFileWatcher) ChangeEvents(fi os.FileInfo) chan bool {
w, err := fsnotify.NewWatcher() w, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
panic(err) panic(err)
@ -65,6 +67,8 @@ func (fw *InotifyFileWatcher) ChangeEvents(_ os.FileInfo) chan bool {
ch := make(chan bool) ch := make(chan bool)
fw.Size = fi.Size()
go func() { go func() {
defer w.Close() defer w.Close()
defer w.RemoveWatch(fw.Filename) defer w.RemoveWatch(fw.Filename)
@ -74,6 +78,7 @@ func (fw *InotifyFileWatcher) ChangeEvents(_ os.FileInfo) chan bool {
prevSize := fw.Size prevSize := fw.Size
evt := <-w.Event evt := <-w.Event
// fmt.Printf("inotify change evt: %v\n", evt)
switch { switch {
case evt.IsDelete(): case evt.IsDelete():
fallthrough fallthrough
@ -82,9 +87,14 @@ func (fw *InotifyFileWatcher) ChangeEvents(_ os.FileInfo) chan bool {
return return
case evt.IsModify(): case evt.IsModify():
fi, _ := os.Stat(fw.Filename) fi, err := os.Stat(fw.Filename)
if err != nil {
// XXX: no panic here
panic(err)
}
fw.Size = fi.Size() fw.Size = fi.Size()
// fmt.Printf("WATCH: prevSize=%d; fs.Size=%d\n", prevSize, fw.Size)
if prevSize > 0 && prevSize > fw.Size { if prevSize > 0 && prevSize > fw.Size {
return return
} }
@ -124,6 +134,7 @@ func (fw *PollingFileWatcher) BlockUntilExists() error {
return err return err
} }
time.Sleep(POLL_DURATION) time.Sleep(POLL_DURATION)
println("blocking..")
} }
panic("unreachable") panic("unreachable")
} }