|
|
@@ -28,18 +28,18 @@ func newWatchHub(capacity int) *watcherHub {
|
|
|
// If recursive is true, the first change after index under prefix will be sent to the event channel.
|
|
|
// If recursive is false, the first change after index at prefix will be sent to the event channel.
|
|
|
// If index is zero, watch will start from the current index + 1.
|
|
|
-func (wh *watcherHub) watch(prefix string, recursive bool, index uint64) (error, <-chan *Event) {
|
|
|
+func (wh *watcherHub) watch(prefix string, recursive bool, index uint64) (<-chan *Event, error) {
|
|
|
eventChan := make(chan *Event, 1)
|
|
|
|
|
|
e, err := wh.EventHistory.scan(prefix, index)
|
|
|
|
|
|
if err != nil {
|
|
|
- return err, nil
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
if e != nil {
|
|
|
eventChan <- e
|
|
|
- return nil, eventChan
|
|
|
+ return eventChan, nil
|
|
|
}
|
|
|
|
|
|
w := &watcher{
|
|
|
@@ -58,57 +58,55 @@ func (wh *watcherHub) watch(prefix string, recursive bool, index uint64) (error,
|
|
|
wh.watchers[prefix] = l
|
|
|
}
|
|
|
|
|
|
- return nil, eventChan
|
|
|
+ return eventChan, nil
|
|
|
}
|
|
|
|
|
|
-func (wh *watcherHub) notify(e *Event) {
|
|
|
+func (wh *watcherHub) notifyWithPath(e *Event, path string, force bool) {
|
|
|
+ l, ok := wh.watchers[path]
|
|
|
|
|
|
- segments := strings.Split(e.Key, "/")
|
|
|
- currPath := "/"
|
|
|
+ if ok {
|
|
|
|
|
|
- // walk through all the paths
|
|
|
- for _, segment := range segments {
|
|
|
- currPath = path.Join(currPath, segment)
|
|
|
+ curr := l.Front()
|
|
|
+ notifiedAll := true
|
|
|
|
|
|
- l, ok := wh.watchers[currPath]
|
|
|
+ for {
|
|
|
|
|
|
- if ok {
|
|
|
+ if curr == nil { // we have reached the end of the list
|
|
|
|
|
|
- curr := l.Front()
|
|
|
- notifiedAll := true
|
|
|
+ if notifiedAll {
|
|
|
+ // if we have notified all watcher in the list
|
|
|
+ // we can delete the list
|
|
|
+ delete(wh.watchers, path)
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
|
|
|
- for {
|
|
|
+ next := curr.Next() // save the next
|
|
|
|
|
|
- if curr == nil { // we have reached the end of the list
|
|
|
+ w, _ := curr.Value.(*watcher)
|
|
|
|
|
|
- if notifiedAll {
|
|
|
- // if we have notified all watcher in the list
|
|
|
- // we can delete the list
|
|
|
- delete(wh.watchers, currPath)
|
|
|
- }
|
|
|
- break
|
|
|
- }
|
|
|
+ if w.recursive || force || e.Key == path {
|
|
|
+ w.eventChan <- e
|
|
|
+ l.Remove(curr)
|
|
|
+ } else {
|
|
|
+ notifiedAll = false
|
|
|
+ }
|
|
|
|
|
|
- next := curr.Next() // save the next
|
|
|
+ curr = next // go to the next one
|
|
|
|
|
|
- w, _ := curr.Value.(*watcher)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- if w.recursive {
|
|
|
- w.eventChan <- e
|
|
|
- l.Remove(curr)
|
|
|
- } else {
|
|
|
- if e.Key == currPath { // only notify the same path
|
|
|
- w.eventChan <- e
|
|
|
- l.Remove(curr)
|
|
|
- } else { // we do not notify all watcher in the list
|
|
|
- notifiedAll = false
|
|
|
- }
|
|
|
- }
|
|
|
+func (wh *watcherHub) notify(e *Event) {
|
|
|
|
|
|
- curr = next // go to the next one
|
|
|
+ segments := strings.Split(e.Key, "/")
|
|
|
|
|
|
- }
|
|
|
- }
|
|
|
+ currPath := "/"
|
|
|
|
|
|
+ // walk through all the paths
|
|
|
+ for _, segment := range segments {
|
|
|
+ currPath = path.Join(currPath, segment)
|
|
|
+ wh.notifyWithPath(e, currPath, false)
|
|
|
}
|
|
|
}
|