Browse Source

Merge pull request #593 from benbjohnson/lock-fix

fix(mod/lock): correct watch index to remove cpu load
Ben Johnson 11 years ago
parent
commit
a60481c6b1
2 changed files with 11 additions and 13 deletions
  1. 4 9
      mod/lock/v2/acquire_handler.go
  2. 7 4
      mod/lock/v2/lock_nodes.go

+ 4 - 9
mod/lock/v2/acquire_handler.go

@@ -165,22 +165,17 @@ func (h *handler) watch(keypath string, index int, closeChan <-chan bool) error
 			return fmt.Errorf("lock watch lookup error: %s", err.Error())
 		}
 		nodes := lockNodes{resp.Node.Nodes}
-		prevIndex := nodes.PrevIndex(index)
+		prevIndex, modifiedIndex := nodes.PrevIndex(index)
 
 		// If there is no previous index then we have the lock.
 		if prevIndex == 0 {
 			return nil
 		}
 
-		// Watch previous index until it's gone.
-		waitIndex := resp.Node.ModifiedIndex
+		// Wait from the last modification of the node.
+		waitIndex := modifiedIndex + 1
 
-		// Since event store has only 1000 histories we should use first node's CreatedIndex if available
-		if firstNode := nodes.First(); firstNode != nil {
-			waitIndex = firstNode.CreatedIndex
-		}
-
-		_, err = h.client.Watch(path.Join(keypath, strconv.Itoa(prevIndex)), waitIndex, false, nil, stopWatchChan)
+		resp, err = h.client.Watch(path.Join(keypath, strconv.Itoa(prevIndex)), uint64(waitIndex), false, nil, stopWatchChan)
 		if err == etcd.ErrWatchStoppedByUser {
 			return fmt.Errorf("lock watch closed")
 		} else if err != nil {

+ 7 - 4
mod/lock/v2/lock_nodes.go

@@ -41,17 +41,20 @@ func (s lockNodes) FindByValue(value string) (*etcd.Node, int) {
 	return nil, 0
 }
 
-// Retrieves the index that occurs before a given index.
-func (s lockNodes) PrevIndex(index int) int {
+// Find the node with the largest index in the lockNodes that is smaller than the given index. Also return the lastModified index of that node.
+func (s lockNodes) PrevIndex(index int) (int, int) {
 	sort.Sort(s)
 
+	// Iterate over each node to find the given index. We keep track of the
+	// previous index on each iteration so we can return it when we match the
+	// index we're looking for.
 	var prevIndex int
 	for _, node := range s.Nodes {
 		idx, _ := strconv.Atoi(path.Base(node.Key))
 		if index == idx {
-			return prevIndex
+			return prevIndex, int(node.ModifiedIndex)
 		}
 		prevIndex = idx
 	}
-	return 0
+	return 0, 0
 }