diff --git a/store/node.go b/store/node.go index 010a97dee..683e6038b 100644 --- a/store/node.go +++ b/store/node.go @@ -116,61 +116,6 @@ func (n *Node) IsDir() bool { return !(n.Children == nil) } -// Remove function remove the node. -func (n *Node) Remove(recursive bool, callback func(path string)) *etcdErr.Error { - - if n.IsDir() && !recursive { - // cannot delete a directory without set recursive to true - return etcdErr.NewError(etcdErr.EcodeNotFile, "", UndefIndex, UndefTerm) - } - - onceBody := func() { - n.internalRemove(recursive, callback) - } - - // this function might be entered multiple times by expire and delete - // every node will only be deleted once. - n.once.Do(onceBody) - - return nil -} - -// internalRemove function will be called by remove() -func (n *Node) internalRemove(recursive bool, callback func(path string)) { - if !n.IsDir() { // key-value pair - _, name := path.Split(n.Path) - - // find its parent and remove the node from the map - if n.Parent != nil && n.Parent.Children[name] == n { - delete(n.Parent.Children, name) - } - - if callback != nil { - callback(n.Path) - } - - // the stop channel has a buffer. just send to it! - n.stopExpire <- true - return - } - - for _, child := range n.Children { // delete all children - child.Remove(true, callback) - } - - // delete self - _, name := path.Split(n.Path) - if n.Parent != nil && n.Parent.Children[name] == n { - delete(n.Parent.Children, name) - - if callback != nil { - callback(n.Path) - } - - n.stopExpire <- true - } -} - // Read function gets the value of the node. // If the receiver node is not a key-value pair, a "Not A File" error will be returned. func (n *Node) Read() (string, *etcdErr.Error) { @@ -195,6 +140,13 @@ func (n *Node) Write(value string, index uint64, term uint64) *etcdErr.Error { return nil } +func (n *Node) ExpirationAndTTL() (*time.Time, int64) { + if n.ExpireTime.Sub(Permanent) != 0 { + return &n.ExpireTime, int64(n.ExpireTime.Sub(time.Now())/time.Second) + 1 + } + return nil, 0 +} + // List function return a slice of nodes under the receiver node. // If the receiver node is not a directory, a "Not A Directory" error will be returned. func (n *Node) List() ([]*Node, *etcdErr.Error) { @@ -251,6 +203,61 @@ func (n *Node) Add(child *Node) *etcdErr.Error { return nil } +// Remove function remove the node. +func (n *Node) Remove(recursive bool, callback func(path string)) *etcdErr.Error { + + if n.IsDir() && !recursive { + // cannot delete a directory without set recursive to true + return etcdErr.NewError(etcdErr.EcodeNotFile, "", UndefIndex, UndefTerm) + } + + onceBody := func() { + n.internalRemove(recursive, callback) + } + + // this function might be entered multiple times by expire and delete + // every node will only be deleted once. + n.once.Do(onceBody) + + return nil +} + +// internalRemove function will be called by remove() +func (n *Node) internalRemove(recursive bool, callback func(path string)) { + if !n.IsDir() { // key-value pair + _, name := path.Split(n.Path) + + // find its parent and remove the node from the map + if n.Parent != nil && n.Parent.Children[name] == n { + delete(n.Parent.Children, name) + } + + if callback != nil { + callback(n.Path) + } + + // the stop channel has a buffer. just send to it! + n.stopExpire <- true + return + } + + for _, child := range n.Children { // delete all children + child.Remove(true, callback) + } + + // delete self + _, name := path.Split(n.Path) + if n.Parent != nil && n.Parent.Children[name] == n { + delete(n.Parent.Children, name) + + if callback != nil { + callback(n.Path) + } + + n.stopExpire <- true + } +} + // Expire function will test if the node is expired. // if the node is already expired, delete the node and return. // if the node is permanent (this shouldn't happen), return at once. diff --git a/store/store.go b/store/store.go index 2c0c9cdb4..966aa49c6 100644 --- a/store/store.go +++ b/store/store.go @@ -75,14 +75,11 @@ func (s *Store) Get(nodePath string, recursive, sorted bool, index uint64, term sort.Sort(e.KVPairs) } - } else { // node is file - e.Value = n.Value + } else { // node is a file + e.Value, _ = n.Read() } - if n.ExpireTime.Sub(Permanent) != 0 { - e.Expiration = &n.ExpireTime - e.TTL = int64(n.ExpireTime.Sub(time.Now())/time.Second) + 1 - } + e.Expiration, e.TTL = n.ExpirationAndTTL() s.Stats.Inc(GetSuccess) @@ -140,10 +137,8 @@ func (s *Store) Update(nodePath string, value string, expireTime time.Time, inde // update ttl n.UpdateTTL(expireTime, s) - if n.ExpireTime.Sub(Permanent) != 0 { - e.Expiration = &n.ExpireTime - e.TTL = int64(expireTime.Sub(time.Now())/time.Second) + 1 - } + e.Expiration, e.TTL = n.ExpirationAndTTL() + s.WatcherHub.notify(e) s.Stats.Inc(UpdateSuccess) @@ -184,10 +179,7 @@ func (s *Store) TestAndSet(nodePath string, prevValue string, prevIndex uint64, n.UpdateTTL(expireTime, s) - if n.ExpireTime.Sub(Permanent) != 0 { - e.Expiration = &n.ExpireTime - e.TTL = int64(expireTime.Sub(time.Now())/time.Second) + 1 - } + e.Expiration, e.TTL = n.ExpirationAndTTL() s.WatcherHub.notify(e) s.Stats.Inc(TestAndSetSuccess) @@ -360,8 +352,7 @@ func (s *Store) internalCreate(nodePath string, value string, incrementalSuffix // Node with TTL if expireTime.Sub(Permanent) != 0 { n.Expire(s) - e.Expiration = &n.ExpireTime - e.TTL = int64(expireTime.Sub(time.Now())/time.Second) + 1 + e.Expiration, e.TTL = n.ExpirationAndTTL() } s.WatcherHub.notify(e)