fsnotify
fsnotify copied to clipboard
API should offer length of pending events
The number of buffered events in a channel can be determined with the len(ch) function... However, the watcher.Events channel returned by the API is actually unbuffered, even though the underlying implementation can buffer some number of events. I propose that a Len() function be added to determine how many events are "pending".
Proof that this is the case... Create a dir /tmp/blah/ and a file /tmp/blah/foo.
Now run the following script, and run touch /tmp/blah/foo periodically within less than 3 seconds, and you'll see the events come in. If you wait more than 3 seconds, the program will print zzz, and at that point, the select is "paused" and you should run the touch command above a few times within 6 seconds. When the six second sleep ends, you'll see however many events suddenly pop out, even though the channel said zero we're waiting. It would be useful to know the number pending before we read from them.
package main
import (
"gopkg.in/fsnotify.v1"
"log"
"time"
)
func main() {
Watch()
}
func Watch() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
err = watcher.Add("/tmp/blah/foo")
if err != nil {
log.Fatal(err)
}
for {
log.Printf("File has %d events pending\n", len(watcher.Events)) //always 0 :(
log.Printf("Waiting...!\n")
select {
case event := <-watcher.Events:
log.Println("Event.Name is: ", event.Name)
case err := <-watcher.Errors:
log.Println("error:", err)
log.Fatal(err)
case <- time.After(3 * time.Second):
log.Println("Zzz...")
time.Sleep(6 * time.Second)
log.Println("Wakeup!")
}
}
}
Hope this was clear enough. Thanks, James
It could be useful. Though for any API addition or change, I'd like to hear from multiple people, so I'm going to let this sit for awhile.
One consideration is that sometimes the underlying OS does buffering of it's own. FSEvents on Mac in particular can even persist events to disk across reboots. I'm not sure how accurate the length returned would be in such situations, but it's worth investigating.
On Fri, Dec 18, 2015 at 10:12 PM, Nathan Youngman [email protected] wrote:
It could be useful. Though for any API addition or change, I'd like to hear from multiple people, so I'm going to let this sit for awhile.
One consideration is that sometimes the underlying OS does buffering of it's own. FSEvents on Mac in particular can even persist events to disk across reboots. I'm not sure how accurate the length returned would be in such situations, but it's worth investigating.
wow, I did not know that it would even buffer events to disk on OSX, but interesting nonetheless!
Per your suggestion, I agree, and I'm fine with other people weighing in. Since I realize I might not have given a clear enough use case, the Len() api would be particularly useful for situations where you have a a bunch of listeners, and you'd like to know if they've temporarily quiesced, or are close to quiet, of if they are still quite busy firing. IOW, if you want to pause one, at least only run your pause when Len() is zero or less than some threshold.
This would often be as part of a heuristic, therefore if a particular backend always buffers internally and this number isn't available for inspection, and thus always returns 0 for the length, this isn't the end of the world as long as it's documented.
Thanks again, James
I don't mind adding new APIs if it solves real-world use cases, but in 9 years, no one has reported any. So this doesn't really seem very important.