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

Watcher: extend Unwatch arguments with Event to be unwatched. #30

Closed
wants to merge 1 commit into from
Closed

Watcher: extend Unwatch arguments with Event to be unwatched. #30

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Sep 27, 2014

This way you can stop watching only specified events, what is necessary and makes it work as comment says.

It does not change how current implementations work (they ignore the value, and passed is always All), but allows it to be utilized.

@rjeczalik
Copy link
Owner

From the runtime view of point we would need Rewatch, which would look like:

type Watcher interface {
  ...
  Rewatch(path string, old, new Event)
  ...
}

For most implementations it would be enough to:

func (x x) Rewatch(path string, _, new Event) {
  x.Unwatch(path)
  x.Watch(path, new)
}

For Windows and FSEvents Rewatch would be a nop, however for inotify it would be an optimalization.

And Rewatch would be used for extending the watch set, e.g. the following calls:

notify.Watch("/dir", creat, notify.Create)
notift.Watch("/dir", delet, notify.Delete)

would call internally:

  • Watch("/dir", notify.Create)
  • Rewatch("/dir", notify.Create, notify.Create | notify.Delete)

instead of:

  • Watch("/dir", notify.Create)
  • Unwatch("/dir")
  • Watch("/dir", notify.Create | notify.Delete)

So basically it enables some optimisations in watch creation/deletion.

@pblaszczyk If Unwatch(string, Event) solves the same use-case as Rewatch, I'd prefer the latter. If it solves different use-case, I'm merging it right away.

@ghost
Copy link
Author

ghost commented Sep 28, 2014

This is more about decreasing number of watched events instead of extend:

notify.Watch("p1", ch1, notify.Create | notify.Delete)
notify.Watch("p1", ch2, notify.Create)
notify.Stop(ch1)

After last line, you no longer want to monitor deletes, only creates. You can Unwatch whole file and Watch it again with remaining observed events or you can simply send to Unwatch Watcher implementation which kind of events are no longer to be observed. This way Watcher impl would choose if it will Unwatch Watch if does not support decreasing number of watched events or simply decrease it using API. Unless you want to call Unwatch and Watch again, but you can lose events in between (yes, I know that not only then but..).

@ppknap
Copy link
Collaborator

ppknap commented Sep 28, 2014

notify.Watch("p1", ch1, notify.Create | notify.Delete)
... 
// arguments
ch := ch1
newevents := []Event{notify.Create | notify.Delete}
...
//internally, globals per dir
mapechanevent := make(map[chan<- EventInfo]Event) // merged events
eventdiff := []Event
...
eventdiff = geteventdiff(mapechanevent[ch], newevents) // will return []Event{notify.Create, notify.Delete}, because mapechanevent[ch] is empty

newmask := Event{0}
for _, e := range eventdiff
  evcounter[e]++
  if  evcounter[e] > 0 {
    newmask |= e
 }
}
//internally 
Watch("/dir", newmask)

notify.Watch("p1", ch2, notify.Create)
// TBD
notify.Stop(ch1)
// TBD

@ppknap
Copy link
Collaborator

ppknap commented Sep 28, 2014

notify.Watch("p1", ch2, notify.Create)
... 
// arguments
ch := ch2
newevents := []Event{notify.Create}
...
//internally, globals per dir
mapechanevent := make(map[chan<- EventInfo]Event) // merged events
eventdiff := []Event
...
eventdiff = geteventdiff(mapechanevent[ch], newevents) // will return []Event{notify.Create},

newmask := Event{0}
for _, e := range eventdiff
  evcounter[e]++
 // notify.Create = 2
 // notify.Delete = 1
  if  evcounter[e] > 0 {
    newmask |= e
 }
}
//internally 
Watch("/dir", newmask)

notify.Stop(ch1)
// TBD

@ppknap
Copy link
Collaborator

ppknap commented Sep 28, 2014

notify.Stop(ch1)
... 
// arguments
ch := ch1
...
//internally, globals per dir
mapechanevent := make(map[chan<- EventInfo]Event) // merged events
eventdiff := []Event
...
eventdiff = geteventdiff(mapechanevent[ch], Event(0)) // will return []Event{notify.Create, notify.Delete},

newmask := Event{0}
for _, e := range eventdiff
  evcounter[e]--
 // notify.Create = 1
 // notify.Delete = 0
  if  evcounter[e] > 0 {
    newmask |= e
 }
}
//internally 
Watch("/dir", newmask)

@rjeczalik
Copy link
Owner

After last line, you no longer want to monitor deletes, only creates. You can Unwatch whole file and
Watch it again with remaining observed events or you can simply send to Unwatch Watcher
implementation which kind of events are no longer to be observed.

That's what Rewatch is for: Rewatch(path, notify.Create | notify.Delete, notify.Create). Mind that for half implementations this optimisation would not be effective.

@ghost
Copy link
Author

ghost commented Sep 28, 2014

Ok, it's different approach (requires you to pass current events), but let it be.

@ghost ghost closed this Sep 28, 2014
@ghost ghost deleted the unwatch branch September 28, 2014 08:32
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants