diff --git a/mod/lock/v2/acquire_handler.go b/mod/lock/v2/acquire_handler.go index 7ca5d84a4..58fc1e8aa 100644 --- a/mod/lock/v2/acquire_handler.go +++ b/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 { diff --git a/mod/lock/v2/lock_nodes.go b/mod/lock/v2/lock_nodes.go index 482621d0f..f7dc0e3c5 100644 --- a/mod/lock/v2/lock_nodes.go +++ b/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 }