mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
fix(mod/lock): correct watch index to remove cpu load
The waitIndex was being pulled from the wrong node in the lock parent which caused the watch to be returned immediately. This caused a continuous set of calls while a client was waiting for a lock.
This commit is contained in:
parent
f922a08a27
commit
dde2b71850
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user