Browse Source

Merge pull request #537 from xiangli-cmu/fix_hidden_watch

fix(watch hidden key)
Xiang Li 12 years ago
parent
commit
8a172322ff
3 changed files with 62 additions and 4 deletions
  1. 12 0
      store/store_test.go
  2. 7 4
      store/watcher_hub.go
  3. 43 0
      store/watcher_hub_test.go

+ 12 - 0
store/store_test.go

@@ -782,6 +782,18 @@ 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)
+	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 {

+ 7 - 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,11 @@ 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 {
+	// if watch path is just a "/", after path will start without "/"
+	// add a "/" to deal with the special case when watchPath is "/"
+	afterPath := path.Clean("/" + keyPath[len(watchPath):])
+	return strings.Contains(afterPath, "/_")
 }

+ 43 - 0
store/watcher_hub_test.go

@@ -0,0 +1,43 @@
+package store
+
+import (
+	"testing"
+)
+
+// TestIsHidden tests isHidden functions.
+func TestIsHidden(t *testing.T) {
+	// watch at "/"
+	// key is "/_foo", hidden to "/"
+	// expected: hidden = true
+	watch := "/"
+	key := "/_foo"
+	hidden := isHidden(watch, key)
+	if !hidden {
+		t.Fatalf("%v should be hidden to %v\n", key, watch)
+	}
+
+	// watch at "/_foo"
+	// key is "/_foo", not hidden to "/_foo"
+	// expected: hidden = false
+	watch = "/_foo"
+	hidden = isHidden(watch, key)
+	if hidden {
+		t.Fatalf("%v should not be hidden to %v\n", key, watch)
+	}
+
+	// watch at "/_foo/"
+	// key is "/_foo/foo", not hidden to "/_foo"
+	key = "/_foo/foo"
+	hidden = isHidden(watch, key)
+	if hidden {
+		t.Fatalf("%v should not be hidden to %v\n", key, watch)
+	}
+
+	// watch at "/_foo/"
+	// key is "/_foo/_foo", hidden to "/_foo"
+	key = "/_foo/_foo"
+	hidden = isHidden(watch, key)
+	if !hidden {
+		t.Fatalf("%v should be hidden to %v\n", key, watch)
+	}
+}