diff --git a/server/v2/tests/delete_handler_test.go b/server/v2/tests/delete_handler_test.go index 2905c68c4..997127a9e 100644 --- a/server/v2/tests/delete_handler_test.go +++ b/server/v2/tests/delete_handler_test.go @@ -24,6 +24,6 @@ func TestV2DeleteKey(t *testing.T) { resp, err = tests.DeleteForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), url.Values{}) body := tests.ReadBody(resp) assert.Nil(t, err, "") - assert.Equal(t, string(body), `{"action":"delete","key":"/foo/bar","prevValue":"XXX","index":2}`, "") + assert.Equal(t, string(body), `{"action":"delete","key":"/foo/bar","prevValue":"XXX","modifiedIndex":2}`, "") }) } diff --git a/server/v2/tests/get_handler_test.go b/server/v2/tests/get_handler_test.go index 0f0054055..b15195873 100644 --- a/server/v2/tests/get_handler_test.go +++ b/server/v2/tests/get_handler_test.go @@ -27,7 +27,7 @@ func TestV2GetKey(t *testing.T) { assert.Equal(t, body["action"], "get", "") assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["value"], "XXX", "") - assert.Equal(t, body["index"], 1, "") + assert.Equal(t, body["modifiedIndex"], 1, "") }) } @@ -54,7 +54,7 @@ func TestV2GetKeyRecursively(t *testing.T) { assert.Equal(t, body["action"], "get", "") assert.Equal(t, body["key"], "/foo", "") assert.Equal(t, body["dir"], true, "") - assert.Equal(t, body["index"], 2, "") + assert.Equal(t, body["modifiedIndex"], 1, "") assert.Equal(t, len(body["kvs"].([]interface{})), 2, "") kv0 := body["kvs"].([]interface{})[0].(map[string]interface{}) @@ -111,7 +111,7 @@ func TestV2WatchKey(t *testing.T) { assert.Equal(t, body["action"], "set", "") assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["value"], "XXX", "") - assert.Equal(t, body["index"], 1, "") + assert.Equal(t, body["modifiedIndex"], 1, "") }) } @@ -164,6 +164,6 @@ func TestV2WatchKeyWithIndex(t *testing.T) { assert.Equal(t, body["action"], "set", "") assert.Equal(t, body["key"], "/foo/bar", "") assert.Equal(t, body["value"], "YYY", "") - assert.Equal(t, body["index"], 2, "") + assert.Equal(t, body["modifiedIndex"], 2, "") }) } diff --git a/server/v2/tests/post_handler_test.go b/server/v2/tests/post_handler_test.go index 655278f22..856633ef0 100644 --- a/server/v2/tests/post_handler_test.go +++ b/server/v2/tests/post_handler_test.go @@ -23,7 +23,7 @@ func TestV2CreateUnique(t *testing.T) { assert.Equal(t, body["action"], "create", "") assert.Equal(t, body["key"], "/foo/bar/1", "") assert.Equal(t, body["dir"], true, "") - assert.Equal(t, body["index"], 1, "") + assert.Equal(t, body["modifiedIndex"], 1, "") // Second POST should add next index to list. resp, _ = tests.PostForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), nil) diff --git a/server/v2/tests/put_handler_test.go b/server/v2/tests/put_handler_test.go index 73f6be91c..3ee642604 100644 --- a/server/v2/tests/put_handler_test.go +++ b/server/v2/tests/put_handler_test.go @@ -22,7 +22,7 @@ func TestV2SetKey(t *testing.T) { resp, err := tests.PutForm(fmt.Sprintf("http://%s%s", s.URL(), "/v2/keys/foo/bar"), v) body := tests.ReadBody(resp) assert.Nil(t, err, "") - assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","index":1}`, "") + assert.Equal(t, string(body), `{"action":"set","key":"/foo/bar","value":"XXX","modifiedIndex":1}`, "") }) } @@ -175,7 +175,7 @@ func TestV2SetKeyCASOnIndexSuccess(t *testing.T) { assert.Equal(t, body["action"], "compareAndSwap", "") assert.Equal(t, body["prevValue"], "XXX", "") assert.Equal(t, body["value"], "YYY", "") - assert.Equal(t, body["index"], 2, "") + assert.Equal(t, body["modifiedIndex"], 2, "") }) } @@ -236,7 +236,7 @@ func TestV2SetKeyCASOnValueSuccess(t *testing.T) { assert.Equal(t, body["action"], "compareAndSwap", "") assert.Equal(t, body["prevValue"], "XXX", "") assert.Equal(t, body["value"], "YYY", "") - assert.Equal(t, body["index"], 2, "") + assert.Equal(t, body["modifiedIndex"], 2, "") }) } diff --git a/store/event.go b/store/event.go index 50d2872da..126ceee4b 100644 --- a/store/event.go +++ b/store/event.go @@ -15,23 +15,23 @@ const ( ) type Event struct { - Action string `json:"action"` - Key string `json:"key, omitempty"` - Dir bool `json:"dir,omitempty"` - PrevValue string `json:"prevValue,omitempty"` - Value string `json:"value,omitempty"` - KVPairs kvPairs `json:"kvs,omitempty"` - Expiration *time.Time `json:"expiration,omitempty"` - TTL int64 `json:"ttl,omitempty"` // Time to live in second - // The index of the etcd state machine when the comment is executed - Index uint64 `json:"index"` + Action string `json:"action"` + + Key string `json:"key, omitempty"` + Dir bool `json:"dir,omitempty"` + PrevValue string `json:"prevValue,omitempty"` + Value string `json:"value,omitempty"` + KVPairs kvPairs `json:"kvs,omitempty"` + Expiration *time.Time `json:"expiration,omitempty"` + TTL int64 `json:"ttl,omitempty"` // Time to live in second + ModifiedIndex uint64 `json:"modifiedIndex"` } func newEvent(action string, key string, index uint64) *Event { return &Event{ - Action: action, - Key: key, - Index: index, + Action: action, + Key: key, + ModifiedIndex: index, } } @@ -47,6 +47,10 @@ func (e *Event) IsCreated() bool { return false } +func (e *Event) Index() uint64 { + return e.ModifiedIndex +} + // Converts an event object into a response object. func (event *Event) Response() interface{} { if !event.Dir { @@ -55,7 +59,7 @@ func (event *Event) Response() interface{} { Key: event.Key, Value: event.Value, PrevValue: event.PrevValue, - Index: event.Index, + Index: event.ModifiedIndex, TTL: event.TTL, Expiration: event.Expiration, } @@ -80,7 +84,7 @@ func (event *Event) Response() interface{} { Key: kv.Key, Value: kv.Value, Dir: kv.Dir, - Index: event.Index, + Index: event.ModifiedIndex, } } return responses diff --git a/store/event_history.go b/store/event_history.go index aaa93d44e..4fd077184 100644 --- a/store/event_history.go +++ b/store/event_history.go @@ -31,9 +31,9 @@ func (eh *EventHistory) addEvent(e *Event) *Event { eh.Queue.insert(e) - eh.LastIndex = e.Index + eh.LastIndex = e.Index() - eh.StartIndex = eh.Queue.Events[eh.Queue.Front].Index + eh.StartIndex = eh.Queue.Events[eh.Queue.Front].ModifiedIndex return e } @@ -62,7 +62,7 @@ func (eh *EventHistory) scan(prefix string, index uint64) (*Event, *etcdErr.Erro for { e := eh.Queue.Events[i] - if strings.HasPrefix(e.Key, prefix) && index <= e.Index { // make sure we bypass the smaller one + if strings.HasPrefix(e.Key, prefix) && index <= e.Index() { // make sure we bypass the smaller one return e, nil } diff --git a/store/event_test.go b/store/event_test.go index 8a70d09a2..dc30ce44d 100644 --- a/store/event_test.go +++ b/store/event_test.go @@ -23,7 +23,7 @@ func TestEventQueue(t *testing.T) { n := eh.Queue.Size for ; n > 0; n-- { e := eh.Queue.Events[i] - if e.Index != uint64(j) { + if e.Index() != uint64(j) { t.Fatalf("queue error!") } j++ @@ -42,19 +42,19 @@ func TestScanHistory(t *testing.T) { eh.addEvent(newEvent(Create, "/foo/foo/foo", 5)) e, err := eh.scan("/foo", 1) - if err != nil || e.Index != 1 { + if err != nil || e.Index() != 1 { t.Fatalf("scan error [/foo] [1] %v", e.Index) } e, err = eh.scan("/foo/bar", 1) - if err != nil || e.Index != 2 { + if err != nil || e.Index() != 2 { t.Fatalf("scan error [/foo/bar] [2] %v", e.Index) } e, err = eh.scan("/foo/bar", 3) - if err != nil || e.Index != 4 { + if err != nil || e.Index() != 4 { t.Fatalf("scan error [/foo/bar/bar] [4] %v", e.Index) } diff --git a/store/node.go b/store/node.go index 9a7196bd3..a7fd7853c 100644 --- a/store/node.go +++ b/store/node.go @@ -51,13 +51,14 @@ func newDir(store *store, nodePath string, createIndex uint64, parent *Node, ACL string, expireTime time.Time) *Node { return &Node{ - Path: nodePath, - CreateIndex: createIndex, - Parent: parent, - ACL: ACL, - ExpireTime: expireTime, - Children: make(map[string]*Node), - store: store, + Path: nodePath, + CreateIndex: createIndex, + ModifiedIndex: createIndex, + Parent: parent, + ACL: ACL, + ExpireTime: expireTime, + Children: make(map[string]*Node), + store: store, } } diff --git a/store/store.go b/store/store.go index 04bacb711..ff78320fe 100644 --- a/store/store.go +++ b/store/store.go @@ -220,6 +220,8 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) { s.worldLock.Lock() defer s.worldLock.Unlock() + nextIndex := s.CurrentIndex + 1 + n, err := s.internalGet(nodePath) if err != nil { // if the node does not exist, return error @@ -227,7 +229,7 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) { return nil, err } - e := newEvent(Delete, nodePath, s.CurrentIndex) + e := newEvent(Delete, nodePath, nextIndex) if n.IsDir() { e.Dir = true @@ -249,7 +251,6 @@ func (s *store) Delete(nodePath string, recursive bool) (*Event, error) { // update etcd index s.CurrentIndex++ - e.Index = s.CurrentIndex s.WatcherHub.notify(e) s.Stats.Inc(DeleteSuccess) @@ -488,7 +489,7 @@ func (s *store) checkDir(parent *Node, dirName string) (*Node, *etcdErr.Error) { return nil, etcdErr.NewError(etcdErr.EcodeNotDir, parent.Path, s.CurrentIndex) } - n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex, parent, parent.ACL, Permanent) + n := newDir(s, path.Join(parent.Path, dirName), s.CurrentIndex+1, parent, parent.ACL, Permanent) parent.Children[dirName] = n diff --git a/store/store_test.go b/store/store_test.go index 898d510ab..5ee58649d 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -81,7 +81,7 @@ func TestStoreCreateValue(t *testing.T) { assert.Nil(t, e.KVPairs, "") assert.Nil(t, e.Expiration, "") assert.Equal(t, e.TTL, 0, "") - assert.Equal(t, e.Index, uint64(1), "") + assert.Equal(t, e.ModifiedIndex, uint64(1), "") } // Ensure that the store can create a new directory if it doesn't already exist. @@ -119,7 +119,7 @@ func TestStoreUpdateValue(t *testing.T) { assert.Equal(t, e.PrevValue, "bar", "") assert.Equal(t, e.Value, "baz", "") assert.Equal(t, e.TTL, 0, "") - assert.Equal(t, e.Index, uint64(2), "") + assert.Equal(t, e.ModifiedIndex, uint64(2), "") e, _ = s.Get("/foo", false, false) assert.Equal(t, e.Value, "baz", "") } diff --git a/store/watcher.go b/store/watcher.go index 2015d0072..87b2e155d 100644 --- a/store/watcher.go +++ b/store/watcher.go @@ -24,7 +24,7 @@ func (w *watcher) notify(e *Event, originalPath bool, deleted bool) bool { // at the file we need to delete. // For example a watcher is watching at "/foo/bar". And we deletes "/foo". The watcher // should get notified even if "/foo" is not the path it is watching. - if (w.recursive || originalPath || deleted) && e.Index >= w.sinceIndex { + if (w.recursive || originalPath || deleted) && e.Index() >= w.sinceIndex { w.eventChan <- e return true }