Browse Source

fix(watch hidden key) Fix hidden keys preventing deeper recursive watches from receiving events
If a watcher has given the correct hidden directory, we should allow it to watch the non-hidden events under that hidden directory. This pull request achieves this by checking if the path after the watching prefix has a "/_" which indicates a hidden key.

Xiang Li 12 years ago
parent
commit
ba98de6ef0
2 changed files with 18 additions and 4 deletions
  1. 13 0
      store/store_test.go
  2. 5 4
      store/watcher_hub.go

+ 13 - 0
store/store_test.go

@@ -782,6 +782,19 @@ func TestStoreWatchExpireWithHiddenKey(t *testing.T) {
 	assert.Equal(t, e.Node.Key, "/foofoo", "")
 }
 
+// Ensure that the store does see hidden key creates if watching deeper than a hidden key in recursive mode.
+func TestStoreWatchRecursiveCreateDeeperThanHiddenKey(t *testing.T) {
+	s := newStore()
+	w, _ := s.Watch("/_foo/bar", true, false, 0)
+	s.Create("/_foo/bar/baz", false, "baz", false, Permanent)
+
+	e := nbselect(w.EventChan)
+	// The NotNil assertion currently fails
+	assert.NotNil(t, e, "")
+	assert.Equal(t, e.Action, "create", "")
+	assert.Equal(t, e.Node.Key, "/_foo/bar/baz", "")
+}
+
 // Performs a non-blocking select on an event channel.
 func nbselect(c <-chan *Event) *Event {
 	select {

+ 5 - 4
store/watcher_hub.go

@@ -127,7 +127,7 @@ func (wh *watcherHub) notifyWatchers(e *Event, nodePath string, deleted bool) {
 			w, _ := curr.Value.(*Watcher)
 
 			originalPath := (e.Node.Key == nodePath)
-			if (originalPath || !isHidden(e.Node.Key)) && w.notify(e, originalPath, deleted) {
+			if (originalPath || !isHidden(nodePath, e.Node.Key)) && w.notify(e, originalPath, deleted) {
 				if !w.stream { // do not remove the stream watcher
 					// if we successfully notify a watcher
 					// we need to remove the watcher from the list
@@ -158,8 +158,9 @@ func (wh *watcherHub) clone() *watcherHub {
 	}
 }
 
-// isHidden checks to see if this path is considered hidden i.e. the
+// isHidden checks to see if key path is considered hidden to watch path i.e. the
 // last element is hidden or it's within a hidden directory
-func isHidden(nodePath string) bool {
-	return strings.Contains(nodePath, "/_")
+func isHidden(watchPath, keyPath string) bool {
+	afterPath := path.Clean("/" + keyPath[len(watchPath):])
+	return strings.Contains(afterPath, "/_")
 }