Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API should offer length of pending events #109

Closed
purpleidea opened this issue Dec 18, 2015 · 3 comments
Closed

API should offer length of pending events #109

purpleidea opened this issue Dec 18, 2015 · 3 comments
Labels

Comments

@purpleidea
Copy link

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

@nathany
Copy link
Contributor

nathany commented Dec 19, 2015

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.

@purpleidea
Copy link
Author

On Fri, Dec 18, 2015 at 10:12 PM, Nathan Youngman notifications@github.com
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

@arp242 arp242 removed the API label Jul 29, 2022
@arp242
Copy link
Member

arp242 commented Apr 28, 2024

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.

@arp242 arp242 closed this as completed Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants